p4-poo/Program.cs
2024-10-03 16:23:08 +02:00

280 lines
9.9 KiB
C#

namespace P4
{
public enum Token
{
None,
FirstPlayer,
SecondPlayer,
}
public class Program
{
public void SetColor(ConsoleColor backgroundColor = ConsoleColor.Black, ConsoleColor forgroundColor = ConsoleColor.White)
{
Console.ForegroundColor = forgroundColor;
Console.BackgroundColor = backgroundColor;
}
static void Main(string[] args)
{
new Program().SetColor();
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();
public void Start(Token[,] board)
{
int pos = 0;
Token currentPlayer = Token.FirstPlayer;
bool placed = false;
while (!CheckWin(board))
{
if (CheckDraw(board))
break;
d.DrawBoard(board);
d.DrawPlayGround(board, currentPlayer, pos);
ConsoleKey key = Console.ReadKey().Key;
switch (key)
{
case ConsoleKey.RightArrow:
pos++;
break;
case ConsoleKey.LeftArrow:
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);
Console.Clear();
// currentplayer est inversé
if (CheckDraw(board))
Console.WriteLine("il y a eu une égalité");
else if (currentPlayer == Token.FirstPlayer)
Console.WriteLine("Le joueur " + "2" + " a gagné");
else if (currentPlayer == Token.SecondPlayer)
Console.WriteLine("Le joueur " + "1" + " a gagné");
Console.WriteLine("La partie à été gagnée en " + Turn(board) + " tours");
}
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(default, ConsoleColor.Red);
Console.Write("5x6");
p.SetColor();
Console.Write(" et ");
p.SetColor(default, 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
{
public void DrawPlayGround(Token[,] board, Token currentPlayer, int pos)
{
for (int x = 0; x < board.GetLength(0); x++)
{
Console.SetCursorPosition(x, 0);
if (pos == x) Console.Write(DrawToken(currentPlayer));
else Console.Write(DrawToken(Token.None));
}
}
public void DrawBoard(Token[,] board)
{
Console.Clear();
for (int y = 0; y < board.GetLength(1); y++)
for (int x = 0; x < board.GetLength(0); x++)
{
Console.SetCursorPosition(x, y + 2);
Console.Write(DrawToken(board[x, y]));
}
}
public char DrawToken(Token token)
{
switch (token)
{
case Token.FirstPlayer:
return 'X';
case Token.SecondPlayer:
return 'O';
case Token.None:
return '.';
default:
return default;
}
}
}
}