Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
246
Task/Tic-tac-toe/C-sharp/tic-tac-toe.cs
Normal file
246
Task/Tic-tac-toe/C-sharp/tic-tac-toe.cs
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace RosettaTicTacToe
|
||||
{
|
||||
class Program
|
||||
{
|
||||
|
||||
/*================================================================
|
||||
*Pieces (players and board)
|
||||
*================================================================*/
|
||||
static string[][] Players = new string[][] {
|
||||
new string[] { "COMPUTER", "X" }, // computer player
|
||||
new string[] { "HUMAN", "O" } // human player
|
||||
};
|
||||
|
||||
const int Unplayed = -1;
|
||||
const int Computer = 0;
|
||||
const int Human = 1;
|
||||
|
||||
// GameBoard holds index into Players[] (0 or 1) or Unplayed (-1) if location not yet taken
|
||||
static int[] GameBoard = new int[9];
|
||||
|
||||
static int[] corners = new int[] { 0, 2, 6, 8 };
|
||||
|
||||
static int[][] wins = new int[][] {
|
||||
new int[] { 0, 1, 2 }, new int[] { 3, 4, 5 }, new int[] { 6, 7, 8 },
|
||||
new int[] { 0, 3, 6 }, new int[] { 1, 4, 7 }, new int[] { 2, 5, 8 },
|
||||
new int[] { 0, 4, 8 }, new int[] { 2, 4, 6 } };
|
||||
|
||||
|
||||
/*================================================================
|
||||
*Main Game Loop (this is what runs/controls the game)
|
||||
*================================================================*/
|
||||
static void Main(string[] args)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Console.Clear();
|
||||
Console.WriteLine("Welcome to Rosetta Code Tic-Tac-Toe for C#.");
|
||||
initializeGameBoard();
|
||||
displayGameBoard();
|
||||
int currentPlayer = rnd.Next(0, 2); // current player represented by Players[] index of 0 or 1
|
||||
Console.WriteLine("The first move goes to {0} who is playing {1}s.\n", playerName(currentPlayer), playerToken(currentPlayer));
|
||||
while (true)
|
||||
{
|
||||
int thisMove = getMoveFor(currentPlayer);
|
||||
if (thisMove == Unplayed)
|
||||
{
|
||||
Console.WriteLine("{0}, you've quit the game ... am I that good?", playerName(currentPlayer));
|
||||
break;
|
||||
}
|
||||
playMove(thisMove, currentPlayer);
|
||||
displayGameBoard();
|
||||
if (isGameWon())
|
||||
{
|
||||
Console.WriteLine("{0} has won the game!", playerName(currentPlayer));
|
||||
break;
|
||||
}
|
||||
else if (isGameTied())
|
||||
{
|
||||
Console.WriteLine("Cat game ... we have a tie.");
|
||||
break;
|
||||
}
|
||||
currentPlayer = getNextPlayer(currentPlayer);
|
||||
}
|
||||
if (!playAgain())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*================================================================
|
||||
*Move Logic
|
||||
*================================================================*/
|
||||
static int getMoveFor(int player)
|
||||
{
|
||||
if (player == Human)
|
||||
return getManualMove(player);
|
||||
else
|
||||
{
|
||||
//int selectedMove = getManualMove(player);
|
||||
//int selectedMove = getRandomMove(player);
|
||||
int selectedMove = getSemiRandomMove(player);
|
||||
//int selectedMove = getBestMove(player);
|
||||
Console.WriteLine("{0} selects position {1}.", playerName(player), selectedMove + 1);
|
||||
return selectedMove;
|
||||
}
|
||||
}
|
||||
|
||||
static int getManualMove(int player)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Console.Write("{0}, enter you move (number): ", playerName(player));
|
||||
ConsoleKeyInfo keyInfo = Console.ReadKey();
|
||||
Console.WriteLine(); // keep the display pretty
|
||||
if (keyInfo.Key == ConsoleKey.Escape)
|
||||
return Unplayed;
|
||||
if (keyInfo.Key >= ConsoleKey.D1 && keyInfo.Key <= ConsoleKey.D9)
|
||||
{
|
||||
int move = keyInfo.KeyChar - '1'; // convert to between 0..8, a GameBoard index position.
|
||||
if (GameBoard[move] == Unplayed)
|
||||
return move;
|
||||
else
|
||||
Console.WriteLine("Spot {0} is already taken, please select again.", move + 1);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Illegal move, please select again.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int getRandomMove(int player)
|
||||
{
|
||||
int movesLeft = GameBoard.Count(position => position == Unplayed);
|
||||
int x = rnd.Next(0, movesLeft);
|
||||
for (int i = 0; i < GameBoard.Length; i++) // walk board ...
|
||||
{
|
||||
if (GameBoard[i] == Unplayed && x < 0) // until we reach the unplayed move.
|
||||
return i;
|
||||
x--;
|
||||
}
|
||||
return Unplayed;
|
||||
}
|
||||
|
||||
// plays random if no winning move or needed block.
|
||||
static int getSemiRandomMove(int player)
|
||||
{
|
||||
int posToPlay;
|
||||
if (checkForWinningMove(player, out posToPlay))
|
||||
return posToPlay;
|
||||
if (checkForBlockingMove(player, out posToPlay))
|
||||
return posToPlay;
|
||||
return getRandomMove(player);
|
||||
}
|
||||
|
||||
// purposely not implemented (this is the thinking part).
|
||||
static int getBestMove(int player)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool checkForWinningMove(int player, out int posToPlay)
|
||||
{
|
||||
posToPlay = Unplayed;
|
||||
foreach (var line in wins)
|
||||
if (twoOfThreeMatchPlayer(player, line, out posToPlay))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool checkForBlockingMove(int player, out int posToPlay)
|
||||
{
|
||||
posToPlay = Unplayed;
|
||||
foreach (var line in wins)
|
||||
if (twoOfThreeMatchPlayer(getNextPlayer(player), line, out posToPlay))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool twoOfThreeMatchPlayer(int player, int[] line, out int posToPlay)
|
||||
{
|
||||
int cnt = 0;
|
||||
posToPlay = int.MinValue;
|
||||
foreach (int pos in line)
|
||||
{
|
||||
if (GameBoard[pos] == player)
|
||||
cnt++;
|
||||
else if (GameBoard[pos] == Unplayed)
|
||||
posToPlay = pos;
|
||||
}
|
||||
return cnt == 2 && posToPlay >= 0;
|
||||
}
|
||||
|
||||
static void playMove(int boardPosition, int player)
|
||||
{
|
||||
GameBoard[boardPosition] = player;
|
||||
}
|
||||
|
||||
static bool isGameWon()
|
||||
{
|
||||
return wins.Any(line => takenBySamePlayer(line[0], line[1], line[2]));
|
||||
}
|
||||
|
||||
static bool takenBySamePlayer(int a, int b, int c)
|
||||
{
|
||||
return GameBoard[a] != Unplayed && GameBoard[a] == GameBoard[b] && GameBoard[a] == GameBoard[c];
|
||||
}
|
||||
|
||||
static bool isGameTied()
|
||||
{
|
||||
return !GameBoard.Any(spot => spot == Unplayed);
|
||||
}
|
||||
|
||||
/*================================================================
|
||||
*Misc Methods
|
||||
*================================================================*/
|
||||
static Random rnd = new Random();
|
||||
|
||||
static void initializeGameBoard()
|
||||
{
|
||||
for (int i = 0; i < GameBoard.Length; i++)
|
||||
GameBoard[i] = Unplayed;
|
||||
}
|
||||
|
||||
static string playerName(int player)
|
||||
{
|
||||
return Players[player][0];
|
||||
}
|
||||
|
||||
static string playerToken(int player)
|
||||
{
|
||||
return Players[player][1];
|
||||
}
|
||||
|
||||
static int getNextPlayer(int player)
|
||||
{
|
||||
return (player + 1) % 2;
|
||||
}
|
||||
|
||||
static void displayGameBoard()
|
||||
{
|
||||
Console.WriteLine(" {0} | {1} | {2}", pieceAt(0), pieceAt(1), pieceAt(2));
|
||||
Console.WriteLine("---|---|---");
|
||||
Console.WriteLine(" {0} | {1} | {2}", pieceAt(3), pieceAt(4), pieceAt(5));
|
||||
Console.WriteLine("---|---|---");
|
||||
Console.WriteLine(" {0} | {1} | {2}", pieceAt(6), pieceAt(7), pieceAt(8));
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static string pieceAt(int boardPosition)
|
||||
{
|
||||
if (GameBoard[boardPosition] == Unplayed)
|
||||
return (boardPosition + 1).ToString(); // display 1..9 on board rather than 0..8
|
||||
return playerToken(GameBoard[boardPosition]);
|
||||
}
|
||||
|
||||
private static bool playAgain()
|
||||
{
|
||||
Console.WriteLine("\nDo you want to play again?");
|
||||
return Console.ReadKey(false).Key == ConsoleKey.Y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue