394 lines
14 KiB
C#
394 lines
14 KiB
C#
namespace P4
|
|
{
|
|
public enum Token
|
|
{
|
|
None,
|
|
FirstPlayer,
|
|
SecondPlayer,
|
|
}
|
|
|
|
public class Program
|
|
{
|
|
public readonly ConsoleColor FIRSTPLAYERCOLOR = ConsoleColor.Cyan;
|
|
public readonly ConsoleColor SECONDPLAYERCOLOR = ConsoleColor.Yellow;
|
|
/*
|
|
|
|
public readonly ConsoleColor FIRSTPLAYERCOLOR = ConsoleColor.Cyan;
|
|
public readonly ConsoleColor SECONDPLAYERCOLOR = ConsoleColor.Yellow;
|
|
|
|
|
|
public readonly ConsoleColor FIRSTPLAYERCOLOR = ConsoleColor.DarkGreen;
|
|
public readonly ConsoleColor SECONDPLAYERCOLOR = ConsoleColor.DarkYellow;
|
|
|
|
*/
|
|
const ConsoleColor backgroundColor = ConsoleColor.DarkCyan;
|
|
const ConsoleColor forgroundColor = ConsoleColor.Green;
|
|
|
|
public void SetColor(ConsoleColor backgroundColor = backgroundColor, ConsoleColor forgroundColor = forgroundColor)
|
|
{
|
|
Console.ForegroundColor = forgroundColor;
|
|
Console.BackgroundColor = backgroundColor;
|
|
}
|
|
|
|
static void Main(string[] args)
|
|
{
|
|
new Program().SetColor();
|
|
Console.Clear();
|
|
Console.CursorVisible = false;
|
|
int[] boardSize = new Board().BoardSize();
|
|
Token[,] board = new Token[boardSize[0], boardSize[1]];
|
|
new Game().Start(board);
|
|
}
|
|
}
|
|
|
|
public class Game
|
|
{
|
|
private Draw d = new Draw();
|
|
private Program p = new Program();
|
|
public void Start(Token[,] board)
|
|
{
|
|
int pos = 0;
|
|
Token currentPlayer = Token.FirstPlayer;
|
|
bool placed = false;
|
|
|
|
Console.Clear();
|
|
d.DrawPlayGroundBorder(board);
|
|
d.DrawBorder(board);
|
|
|
|
while (!CheckWin(board))
|
|
{
|
|
if (CheckDraw(board))
|
|
break;
|
|
d.DrawBoard(board);
|
|
d.DrawPlayGround(board, currentPlayer, pos);
|
|
|
|
ConsoleKey key = Console.ReadKey(true).Key;
|
|
switch (key)
|
|
{
|
|
case ConsoleKey.RightArrow:
|
|
if (pos < board.GetLength(0) - 1)
|
|
pos++;
|
|
break;
|
|
|
|
case ConsoleKey.LeftArrow:
|
|
if (pos > 0)
|
|
pos--;
|
|
break;
|
|
|
|
case ConsoleKey.Enter:
|
|
case ConsoleKey.Spacebar:
|
|
placed = PlaceToken(board, currentPlayer, pos);
|
|
if (placed && currentPlayer == Token.FirstPlayer)
|
|
currentPlayer = Token.SecondPlayer;
|
|
else if (placed && currentPlayer == Token.SecondPlayer)
|
|
currentPlayer = Token.FirstPlayer;
|
|
|
|
break;
|
|
}
|
|
}
|
|
d.DrawBoard(board);
|
|
d.DrawPlayGround(board, currentPlayer, pos);
|
|
p.SetColor();
|
|
Console.Clear();
|
|
// currentplayer est inversé
|
|
if (CheckDraw(board))
|
|
Console.WriteLine("il y a eu une égalité");
|
|
else if (currentPlayer == Token.FirstPlayer)
|
|
{
|
|
Console.Write("Le ");
|
|
p.SetColor(forgroundColor: p.SECONDPLAYERCOLOR);
|
|
Console.Write("joueur 2");
|
|
p.SetColor();
|
|
Console.WriteLine(" a gagné");
|
|
|
|
}
|
|
else if (currentPlayer == Token.SecondPlayer)
|
|
{
|
|
Console.Write("Le ");
|
|
p.SetColor(forgroundColor: p.FIRSTPLAYERCOLOR);
|
|
Console.Write("joueur 1");
|
|
p.SetColor();
|
|
Console.WriteLine(" a gagné");
|
|
}
|
|
Console.WriteLine("La partie à été gagnée en " + Turn(board) + " tours");
|
|
Console.ReadLine();
|
|
}
|
|
|
|
static int Turn(Token[,] board)
|
|
{
|
|
int count = 0; // compteur
|
|
for (int y = 0; y < board.GetLength(1); y++)
|
|
{
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
if (board[x, y] != 0)
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
private bool CheckDraw(Token[,] board)
|
|
{
|
|
for (int y = 0; y < board.GetLength(1); y++)
|
|
{
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
if (board[x, y] == 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private bool CheckWin(Token[,] board)
|
|
{
|
|
Token[] players = {Token.FirstPlayer, Token.SecondPlayer};
|
|
// boucle qui alterne entre les joueurs 1 et 2
|
|
foreach (var j in players)
|
|
{
|
|
// boucle qui fait toutes les colonnes
|
|
for (int y = 0; y < board.GetLength(1); y++)
|
|
{
|
|
// boucle qui fait toute la valeur des colonnes
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
// on check les bordures horizontales
|
|
if (x + 3 < board.GetLength(0))
|
|
{
|
|
// on check les 4 prochains jetons dans le sens horizontal
|
|
if (board[x, y] == j &&
|
|
board[x + 1, y] == j &&
|
|
board[x + 2, y] == j &&
|
|
board[x + 3, y] == j)
|
|
{
|
|
// on retourne vrai si la condition est respectée
|
|
return true;
|
|
}
|
|
}
|
|
// on check les bordure verticales
|
|
if (y + 3 < board.GetLength(1))
|
|
{
|
|
// on check les 4 prochains jetons dans le sens vertical
|
|
if (board[x, y] == j &&
|
|
board[x, y + 1] == j &&
|
|
board[x, y + 2] == j &&
|
|
board[x, y + 3] == j)
|
|
{
|
|
// on retourne vrai si la condition est respectée
|
|
return true;
|
|
}
|
|
}
|
|
// on check les bordures horizontales et verticales
|
|
if (y + 3 < board.GetLength(1) && x + 3 < board.GetLength(0))
|
|
{
|
|
// on check les 4 prochains jetons dans le sens horizontal et vertical
|
|
if (board[x, y] == j &&
|
|
board[x + 1, y + 1] == j &&
|
|
board[x + 2, y + 2] == j &&
|
|
board[x + 3, y + 3] == j)
|
|
{
|
|
// on retourne vrai si la condition est respectée
|
|
return true;
|
|
}
|
|
}
|
|
// on check les bordures horizontales et verticales
|
|
if (y - 3 > 0 && x + 3 < board.GetLength(0))
|
|
{
|
|
// on check les 4 prochains jetons dans le sens horizontal et vertical
|
|
if (board[x, y] == j &&
|
|
board[x + 1, y - 1] == j &&
|
|
board[x + 2, y - 2] == j &&
|
|
board[x + 3, y - 3] == j)
|
|
{
|
|
// on retourne vrai si la condition est respectée
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// si rien n'a été trouvé, on retourne false
|
|
return false;
|
|
}
|
|
|
|
private bool PlaceToken(Token[,] board, Token currentPlayer, int pos)
|
|
{
|
|
for (int i = board.GetLength(1) - 1; i >= 0; i--)
|
|
{
|
|
if (board[pos, i] != Token.None) continue;
|
|
board[pos, i] = currentPlayer;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
public class Board
|
|
{
|
|
private Program p = new Program();
|
|
public int[] BoardSize()
|
|
{
|
|
int[] boardSize = { 0, 0 }; // initialisation de la taille
|
|
string[] input = { "", "" }; // initialisation de l'entrée utilisateur
|
|
// écriture des instructions en couleur grâce à la méthode WriteColor
|
|
Console.Write("La taille doit être comprise entre ");
|
|
p.SetColor(forgroundColor: ConsoleColor.Red);
|
|
Console.Write("5x6");
|
|
p.SetColor();
|
|
Console.Write(" et ");
|
|
p.SetColor(forgroundColor: ConsoleColor.Red);
|
|
Console.Write("13x16\n");
|
|
p.SetColor();
|
|
Console.WriteLine("exemple: 6x7 (6 lignes et 7 colonnes)");
|
|
Console.Write("taille: ");
|
|
|
|
// récupération de l'entrée utilisateur dans une liste grâce à un split
|
|
input = Console.ReadLine().Split('x');
|
|
|
|
// on essaye de Parse en int les entrées, sinon on fait une récursion
|
|
try
|
|
{
|
|
boardSize[0] = int.Parse(input[1]);
|
|
boardSize[1] = int.Parse(input[0]);
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("La taille est invalide. réessayer");
|
|
return BoardSize();
|
|
}
|
|
|
|
// on check si les entrées sont incorrectes si oui on fait une récursion
|
|
if (boardSize[1] <= 5 || boardSize[1] >= 13 || boardSize[0] <= 6 || boardSize[0] >= 16)
|
|
{
|
|
Console.WriteLine("La taille est invalide. réessayer");
|
|
return BoardSize();
|
|
}
|
|
|
|
// et si tous les checks sont passés, on retourne la taille
|
|
Console.WriteLine("taille valide");
|
|
return boardSize;
|
|
}
|
|
}
|
|
|
|
|
|
public class Draw
|
|
{
|
|
private Program p = new Program();
|
|
private int topSpacing = 2;
|
|
public void DrawPlayGroundBorder(Token[,] board)
|
|
{
|
|
Console.SetCursorPosition(0, topSpacing);
|
|
Console.Write("╔═══");
|
|
for (int x = 0; x < board.GetLength(0) - 1; x++)
|
|
{
|
|
Console.Write("╦═══");
|
|
}
|
|
Console.Write("╗");
|
|
|
|
for (int y = 0; y < board.GetLength(1); y++)
|
|
{
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
Console.SetCursorPosition(x * 4, y * 2 + topSpacing + 1);
|
|
Console.Write("║");
|
|
}
|
|
Console.Write(" ║");
|
|
}
|
|
|
|
Console.SetCursorPosition(0, topSpacing + 2);
|
|
Console.Write("╚═══");
|
|
for (int x = 0; x < board.GetLength(0) - 1; x++)
|
|
{
|
|
Console.Write("╩═══");
|
|
}
|
|
Console.Write("╝");
|
|
}
|
|
|
|
public void DrawPlayGround(Token[,] board, Token currentPlayer, int pos)
|
|
{
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
Console.SetCursorPosition(x*4+2, topSpacing + 1);
|
|
|
|
if (pos == x) Console.Write(DrawToken(currentPlayer));
|
|
else Console.Write(DrawToken(Token.None));
|
|
}
|
|
}
|
|
|
|
public void DrawBorder(Token[,] board)
|
|
{
|
|
int playgroundSpacing = topSpacing + 3;
|
|
Console.SetCursorPosition(0, playgroundSpacing);
|
|
Console.Write("╔═══");
|
|
for (int x = 0; x < board.GetLength(0) - 1; x++)
|
|
{
|
|
Console.Write("╦═══");
|
|
}
|
|
Console.Write("╗");
|
|
|
|
for (int y = 0; y < board.GetLength(1); y++)
|
|
{
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
Console.SetCursorPosition(x * 4, y * 2 + playgroundSpacing + 1);
|
|
Console.Write("║");
|
|
}
|
|
Console.Write(" ║");
|
|
}
|
|
|
|
for (int y = 0; y < board.GetLength(1) - 1; y++)
|
|
{
|
|
Console.SetCursorPosition(0, y * 2 + playgroundSpacing + 2);
|
|
Console.Write("╠═══");
|
|
for (int x = 1; x < board.GetLength(0); x++)
|
|
{
|
|
Console.SetCursorPosition(x * 4, y * 2 + playgroundSpacing + 2);
|
|
Console.Write("╬═══");
|
|
}
|
|
Console.Write("╣");
|
|
}
|
|
|
|
Console.SetCursorPosition(0, board.GetLength(1) * 2 + playgroundSpacing);
|
|
Console.Write("╚═══");
|
|
for (int x = 0; x < board.GetLength(0) - 1; x++)
|
|
{
|
|
Console.Write("╩═══");
|
|
}
|
|
Console.Write("╝");
|
|
}
|
|
|
|
public void DrawBoard(Token[,] board)
|
|
{
|
|
int playgroundSpacing = topSpacing + 3;
|
|
for (int y = 0; y < board.GetLength(1); y++)
|
|
for (int x = 0; x < board.GetLength(0); x++)
|
|
{
|
|
Console.SetCursorPosition(x*4+2, y*2 + playgroundSpacing + 1);
|
|
Console.Write("{0}", DrawToken(board[x, y]));
|
|
}
|
|
}
|
|
|
|
public string DrawToken(Token token)
|
|
{
|
|
switch (token)
|
|
{
|
|
case Token.FirstPlayer:
|
|
p.SetColor(forgroundColor: p.FIRSTPLAYERCOLOR);
|
|
return "■";
|
|
case Token.SecondPlayer:
|
|
p.SetColor(forgroundColor: p.SECONDPLAYERCOLOR);
|
|
return "■";
|
|
case Token.None:
|
|
p.SetColor(forgroundColor: ConsoleColor.DarkGray);
|
|
return "≡";
|
|
default:
|
|
return default;
|
|
}
|
|
}
|
|
}
|
|
}
|