PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tic Tac Toe die zweite


Ph03n!X
2005-12-09, 12:16:20
Hi habe jetzt den Singleplayer jetzt fertiggestellt. Sprich Spieler gegen Spieler.
Schaffe es aber nicht den Multiplayer Spieler gegen Ki fertigzustellen.

Und wollte fragen ob mir da jemand helfen kann wenn ich ihm das Prog schicke?

MeLLe
2005-12-09, 15:11:58
So lernste doch aber nix bei ... :down:

Wo genau kommste denn net weiter, was bereitet dir Sorgen? Wir helfen gern weiter, aber direkt für dich "Arbeiten" wird keiner :|

Ph03n!X
2005-12-10, 17:26:49
naja ich habe wie gesagt den Spieler gegen Spieler Modus soweit fertig und jetzt mit Computer gegen Spieler angefangen , und da gibts Probleme.

Abe Ghiran
2005-12-10, 17:56:11
... und da gibts Probleme.

Welcher Art? Sonst wäre es vielleicht ne gute Idee, mit einem dummen Computerspieler anzufangen, der z.b. aus der Menge der möglichen Züge einen zufällig auswählt. Dann kann man sich erst mal darauf konzentrieren, daß der Spielablauf bei Mensch vs. Computer fehlerfrei implementiert ist.

Grüße, Jan

Ph03n!X
2005-12-11, 11:58:19
also auf Ki Stufe leicht will ich das über eine Zufallszahl lösen geht auch , der setzt dann entsprechend aber ab dem 3 Zug setzt der PC nicht mehr und ich finde den Fehler nicht.

MeLLe
2005-12-11, 17:45:58
A bissl Code würd uns ungemein helfen ... und wir dir im Gegenzug dann sicher auch =)

Ph03n!X
2005-12-12, 14:31:29
poste nacher mal meinen Schwer Computer Code

Expandable
2005-12-21, 23:29:57
Hallo allerseits,

ich hatte heute etwas Zeit, da habe ich mal schnell in C# und .NET 2.0 mit Visual Studio 2005 ein Tic Tac Toe programmiert, das man gegen den Computer spielen kann. Dieser versucht zunächst zu verhindern, dass der Spieler eine 3er-Riehe bekommt. Dann versucht er, eine eigene aufzubauen, falls er bereits einen oder zwei der Felder eine Reihe/Spalte/Diagonale hat und die anderen beide/der andere noch frei ist. Andernfalls nimmt er zufällig eine Position ein.

Hier der Download, falls jemand das Spielchen mal ausprobieren möchte: www.control-online.net/downloads/Tic Tac Toe.exe

Anbei noch der Source Code. Falls jemand Zeit und Lust hat, sich den mal näher anzuschauen - nur zu! Bin für jede Kritik dankbar! Vor allem, ob man die Funktion, in der die CPU strategisch agiert, irgendwie besser schreiben könnte...



TicTacToeForm.cs:
namespace Tic_Tac_Toe
{
enum player { AI, human };
enum fieldStatus { AI, human, empty };

public partial class TicTacToeForm : Form
{
private GameLogic logic;
private GameStatus status;
private AI CPU;

public TicTacToeForm()
{
status = new GameStatus();
CPU = new AI(status);
logic = new GameLogic(status, CPU);

InitializeComponent();

RegisterButtons();
status.WinsCPU = lbl_wins_CPU_num;
status.WinsHuman = lbl_wins_human_num;
status.WinsTied = lbl_wins_tied_num;

logic.StartRound();
}

private void RegisterButtons()
{
Button[,] buttons = new Button[3, 3];
buttons[0, 0] = btn_0_0;
buttons[0, 1] = btn_0_1;
buttons[0, 2] = btn_0_2;
buttons[1, 0] = btn_1_0;
buttons[1, 1] = btn_1_1;
buttons[1, 2] = btn_1_2;
buttons[2, 0] = btn_2_0;
buttons[2, 1] = btn_2_1;
buttons[2, 2] = btn_2_2;

status.RegisterButtons(buttons);
status.ResetFields();
}

private void btn_0_0_Click(object sender, EventArgs e)
{
logic.Click(0, 0);
}

private void btn_0_1_Click(object sender, EventArgs e)
{
logic.Click(0, 1);
}

private void btn_0_2_Click(object sender, EventArgs e)
{
logic.Click(0, 2);
}

private void btn_1_0_Click(object sender, EventArgs e)
{
logic.Click(1, 0);
}

private void btn_1_1_Click(object sender, EventArgs e)
{
logic.Click(1, 1);
}

private void btn_1_2_Click(object sender, EventArgs e)
{
logic.Click(1, 2);
}

private void btn_2_0_Click(object sender, EventArgs e)
{
logic.Click(2, 0);
}

private void btn_2_1_Click(object sender, EventArgs e)
{
logic.Click(2, 1);
}

private void btn_2_2_Click(object sender, EventArgs e)
{
logic.Click(2, 2);
}
}
}

GameLogic.cs:
namespace Tic_Tac_Toe
{
class GameLogic
{
private player currentPlayer;

private GameStatus status;
private AI CPU;

public GameLogic(GameStatus status, AI CPU)
{
this.status = status;
this.CPU = CPU;
}

internal void Click(int row, int col)
{
status.SetFieldsClickable(false);
status.UpdateFields(row, col, currentPlayer);

// See if current player filled a row/col/diagonal, he won
// if there are no fields left to fill, the game's also finished
if (status.GameOver() == true)
{
string infoStr = "";

if (status.Winner == fieldStatus.AI)
infoStr = "Sie haben leider verloren!";
else if (status.Winner == fieldStatus.human)
infoStr = "Gratulation, Sie haben gewonnen!";
else
infoStr = "Unentschieden!";

MessageBox.Show(infoStr, "GameOver!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

status.UpdateStats();
status.ResetFields();
}

StartRound();
}

internal void StartRound()
{
currentPlayer = currentPlayer == player.AI ? player.human : player.AI;
if (currentPlayer == player.AI)
{
CPU.CalculateNextMove();
Click(CPU.Row, CPU.Col);
}
else
status.SetFieldsClickable(true);
}
}
}

AI.cs:
namespace Tic_Tac_Toe
{
class AI
{
private GameStatus status;

private int row;
private int col;

public AI(GameStatus status)
{
this.status = status;
}

internal void CalculateNextMove()
{
// The AI first tries to prevent the player from winning
// If the player is not in a good position, the AI tries to
// win, if it can't, it just clicks somewhere
if (PlayStrategically(fieldStatus.human, fieldStatus.human) == true)
return;
else if (PlayStrategically(fieldStatus.AI, fieldStatus.AI) == true)
return;
else if (PlayStrategically(fieldStatus.AI, fieldStatus.empty) == true)
return;
else
ClickSomewhere();
//System.Windows.Forms.MessageBox.Show("row: " + row.ToString() + " Col: " + col.ToString());
return;
}

private bool PlayStrategically(fieldStatus owner1, fieldStatus owner2)
{
fieldStatus[,] fields = status.Fields;

for (int i = 0; i < 3; ++i)
{
// Check rows
if (fields[i, 0] == owner1 && fields[i, 1] == owner2 && fields[i, 2] == fieldStatus.empty)
{
row = i;
col = 2;
return true;
}
if (fields[i, 1] == owner1 && fields[i, 2] == owner2 && fields[i, 0] == fieldStatus.empty)
{
row = i;
col = 0;
return true;
}
if (fields[i, 0] == owner1 && fields[i, 2] == owner2 && fields[i, 1] == fieldStatus.empty)
{
row = i;
col = 1;
return true;
}

// Check cols
if (fields[0, i] == owner1 && fields[1, i] == owner2 && fields[2, i] == fieldStatus.empty)
{
row = 2;
col = i;
return true;
}
if (fields[1, i] == owner1 && fields[2, i] == owner2 && fields[0, i] == fieldStatus.empty)
{
row = 0;
col = i;
return true;
}
if (fields[0, i] == owner1 && fields[2, i] == owner2 && fields[1, i] == fieldStatus.empty)
{
row = 1;
col = i;
return true;
}
}

// Check diagonals
if (fields[0, 0] == owner1 && fields[1, 1] == owner2 && fields[2, 2] == fieldStatus.empty)
{
row = 2;
col = 2;
return true;
}
if (fields[0, 0] == owner1 && fields[2, 2] == owner2 && fields[1, 1] == fieldStatus.empty)
{
row = 1;
col = 1;
return true;
}
if (fields[1, 1] == owner1 && fields[2, 2] == owner2 && fields[0, 0] == fieldStatus.empty)
{
row = 0;
col = 0;
return true;
}
if (fields[0, 2] == owner1 && fields[1, 1] == owner2 && fields[2, 0] == fieldStatus.empty)
{
row = 2;
col = 0;
return true;
}
if (fields[0, 2] == owner1 && fields[2, 0] == owner2 && fields[1, 1] == fieldStatus.empty)
{
row = 1;
col = 1;
return true;
}
if (fields[1, 1] == owner1 && fields[2, 0] == owner2 && fields[0, 2] == fieldStatus.empty)
{
row = 0;
col = 2;
return true;
}

return false;
}

private void ClickSomewhere()
{
Random getRandomNumber = new Random();

do
{
row = getRandomNumber.Next(3);
col = getRandomNumber.Next(3);
}
while (status.AlreadyClicked(row, col) == true);

return;
}

public int Row
{
get { return row; }
}

public int Col
{
get { return col; }
}
}
}

GameStatus.cs:
namespace Tic_Tac_Toe
{
class GameStatus
{
private Button[,] buttons;
private fieldStatus[,] fields;

private Color humanColor;
private Color AIColor;

private Label winsCPU;
private Label winsHuman;
private Label winsTied;
private fieldStatus winner;

private int roundsPlayed = 0;

public GameStatus()
{
humanColor = Color.Red;
AIColor = Color.Blue;

fields = new fieldStatus[3, 3];
winner = fieldStatus.empty;
}

internal void RegisterButtons(System.Windows.Forms.Button[,] buttons)
{
this.buttons = buttons;
}

internal void UpdateFields(int row, int col, player player)
{
++roundsPlayed;

if (player == player.AI)
{
fields[row, col] = fieldStatus.AI;
buttons[row, col].BackColor = AIColor;
}
else
{
fields[row, col] = fieldStatus.human;
buttons[row, col].BackColor = humanColor;
}

buttons[row, col].Enabled = false;
}

internal void ResetFields()
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
buttons[i, j].BackColor = SystemColors.Control;
fields[i, j] = fieldStatus.empty;
}
}

winner = fieldStatus.empty;
roundsPlayed = 0;
}

internal bool GameOver()
{
bool tmpGameOver = false;

if (CheckForFilledRows() == true)
tmpGameOver = true;
else if (CheckForFilledCols() == true)
tmpGameOver = true;
else if (CheckForFilledDiagonal() == true)
tmpGameOver = true;

if (tmpGameOver == false && roundsPlayed == 9)
{
winner = fieldStatus.empty;
tmpGameOver = true;
}

return tmpGameOver;
}

private bool CheckForFilledRows()
{
for (int i = 0; i < 3; ++i)
{
if (fields[i, 0] != fieldStatus.empty && (fields[i, 0] == fields[i, 1] && fields[i, 0] == fields[i, 2]))
{
winner = fields[i, 0];
return true;
}
}

return false;
}

private bool CheckForFilledCols()
{
for (int i = 0; i < 3; ++i)
{
if (fields[0, i] != fieldStatus.empty && (fields[0, i] == fields[1, i] && fields[0, i] == fields[2, i]))
{
winner = fields[0, i];
return true;
}
}

return false;
}

private bool CheckForFilledDiagonal()
{
if (fields[0, 0] != fieldStatus.empty && (fields[0, 0] == fields[1, 1] && fields[0, 0] == fields[2, 2]))
{
winner = fields[0, 0];
return true;
}

if (fields[2, 0] != fieldStatus.empty && (fields[2, 0] == fields[1, 1] && fields[2, 0] == fields[0, 2]))
{
winner = fields[2, 0];
return true;
}

return false;
}

internal void UpdateStats()
{
if (winner == fieldStatus.AI)
winsCPU.Text = (1 + (System.Int32.Parse(winsCPU.Text))).ToString();
else if (winner == fieldStatus.human)
winsHuman.Text = (1 + (System.Int32.Parse(winsHuman.Text))).ToString();
else
winsTied.Text = (1 + (System.Int32.Parse(winsTied.Text))).ToString();
}

internal void SetFieldsClickable(bool clickable)
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
if (fields[i, j] == fieldStatus.empty)
buttons[i, j].Enabled = clickable;
}
}
}

internal bool AlreadyClicked(int row, int col)
{
if (fields[row, col] != fieldStatus.empty)
return true;

return false;
}

public Label WinsCPU
{
get { return winsCPU; }
set { winsCPU = value; }
}

public Label WinsHuman
{
get { return winsHuman; }
set { winsHuman = value; }
}

public Label WinsTied
{
get { return winsTied; }
set { winsTied = value; }
}

public fieldStatus Winner
{
get { return winner; }
}

public fieldStatus[,] Fields
{
get { return fields; }
}
}
}