// Analyses a given situation and returns its "positivity" // Game lost -> 0 // Game won -> 1 // Other cases -> Proportion of allied pieces in all the pieces in game private float LightAnalysis(PieceState[][] table) { Team winner = InfoGiver.HasGameEnded(table); if (winner == team) { return(1); } if (winner == Team.none) { int allies = 0; int total = 0; // Counting the allied pieces and all the pieces for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (table[i][j] != null) { total += 1; if (table[i][j].team == team) { allies += 1; } } } } return((float)allies / (float)total); } return(0); }
// Analyses all the possible turns and returns the most positive one private TurnResponse DeepAnalysis() { BoardState board = InfoGiver.board; List <TurnResponse> possibleTurns = GetAllTurns(); List <TurnResponse> bestTurns = new List <TurnResponse>(); float bestPositivity = 0; foreach (TurnResponse turn in possibleTurns) { BoardState newBoard = InfoGiver.ApplyTurn(board, turn); float positivity = LightAnalysis(newBoard.table); if (bestPositivity < positivity) { bestTurns = new List <TurnResponse>(); bestTurns.Add(turn); bestPositivity = positivity; } else if (bestPositivity == positivity) { bestTurns.Add(turn); } } if (bestTurns.Count == 0) { return(null); } int randomIndex = Random.Range(0, bestTurns.Count); return(bestTurns[randomIndex]); }
// Makes the list of all the possible turns, then picks up a random one public override TurnResponse PlayTurn() { List <TurnResponse> possibleTurns = new List <TurnResponse>(); PieceState[][] table = InfoGiver.table; // Iterates over all the table twice to find all the possible turns (yes this is disgusting, but done in 1 second) TurnResponse tr = null; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { for (int k = 0; k < 5; k++) { for (int l = 0; l < 5; l++) { if (team == Team.A) { tr = new TurnResponse(InfoGiver.cardA1.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardA1, InfoGiver.cardA2, Team.A, tr)) { possibleTurns.Add(tr); } tr = new TurnResponse(InfoGiver.cardA2.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardA1, InfoGiver.cardA2, Team.A, tr)) { possibleTurns.Add(tr); } } if (team == Team.B) { tr = new TurnResponse(InfoGiver.cardB1.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardB1, InfoGiver.cardB2, Team.B, tr)) { possibleTurns.Add(tr); } tr = new TurnResponse(InfoGiver.cardB2.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardB1, InfoGiver.cardB2, Team.B, tr)) { possibleTurns.Add(tr); } } } } } } if (possibleTurns.Count == 0) { return(null); } int rand = Random.Range(0, possibleTurns.Count); return(possibleTurns[rand]); }
public BoardState() { this.table = InfoGiver.PieceTableToPieceStateTable(Board.instance.table); this.cardA1 = GameManager.instance.cardA1; this.cardA2 = GameManager.instance.cardA2; this.cardB1 = GameManager.instance.cardB1; this.cardB2 = GameManager.instance.cardB2; this.freeCard = GameManager.instance.freeCard; this.currentTeam = GameManager.instance.currentPlayer; }
private List <TurnResponse> GetAllTurns() { List <TurnResponse> possibleTurns = new List <TurnResponse>(); PieceState[][] table = InfoGiver.table; // Iterates over all the table twice to find all the possible turns (yes this is disgusting, but done in 1 second) TurnResponse tr = null; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { for (int k = 0; k < 5; k++) { for (int l = 0; l < 5; l++) { if (team == Team.A) { tr = new TurnResponse(InfoGiver.cardA1.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardA1, InfoGiver.cardA2, Team.A, tr)) { possibleTurns.Add(tr); } tr = new TurnResponse(InfoGiver.cardA2.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardA1, InfoGiver.cardA2, Team.A, tr)) { possibleTurns.Add(tr); } } if (team == Team.B) { tr = new TurnResponse(InfoGiver.cardB1.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardB1, InfoGiver.cardB2, Team.B, tr)) { possibleTurns.Add(tr); } tr = new TurnResponse(InfoGiver.cardB2.cardName, new Vector2Int(i, j), new Vector2Int(k, l)); if (InfoGiver.IsTurnValid(table, InfoGiver.cardB1, InfoGiver.cardB2, Team.B, tr)) { possibleTurns.Add(tr); } } } } } } return(possibleTurns); }
static void Main(string[] args) { //Class instances InfoGiver infoGive = new InfoGiver(); Checker check = new Checker(); Drawer draw = new Drawer(); //Dynamic arrays cuz i'm cool List<char> usedLetters = new List<char>(); List<char> letter = new List<char>(); //5 lives is good ? int lives = 5; string word; //Games starts and runs while the user wants infoGive.giveUserInfo(); while(true) { Console.WriteLine( "If you quit press Q if you wanna play press any other key!"); ConsoleKeyInfo key = Console.ReadKey(); Console.WriteLine(); if (key.KeyChar == 'Q' || key.KeyChar == 'q') { Console.Clear(); Console.WriteLine("Exiting the game"); Thread.Sleep(1000); break; } else { Console.Clear(); letter.Clear(); usedLetters.Clear(); lives = 5; word = infoGive.generateWords(); letter.AddRange(draw.splitLetter(word)); infoGive.giveWordExplanation(word); while (lives != 0) { Console.Clear(); infoGive.giveWordExplanation(word); draw.writeLives(lives); Console.WriteLine( "Give me a letter"); draw.drawUnderscores(usedLetters, letter); if(!(usedLetters.Count == 0)) { check.checkIfRightGuess(letter); } while (true) { if (check.checkInput(ref usedLetters) == true) { break; } } if (!check.checkIfRightGuess(letter)) { lives--; } if (check.checkIfWordIsGuessed(usedLetters, letter)) { Console.Clear(); draw.drawUnderscores(usedLetters, letter); Console.WriteLine( "And you have guessed the word!"); break; } if (lives == 0) { draw.writeLives(lives); Console.WriteLine( "Sorry endgame"); } } Console.WriteLine(); } } }
// Does a depth-first traversal of all the possibilities (with a max depth) to get the best path private System.Tuple <TurnResponse, float> DeepAnalysis(BoardState board, Team team, int depth) { // If the game is won or lost, immediately return null and the positivity Team winner = InfoGiver.HasGameEnded(board.table); if (winner != Team.none) { return(new System.Tuple <TurnResponse, float>(null, winner == team ? 1 : 0)); } List <TurnResponse> possibleTurns = GetAllTurns(board, team); // Makes the list of all the equivalent best turns, by traversing the possible turns and analysing their outcomes List <System.Tuple <TurnResponse, float> > bestTurns = new List <System.Tuple <TurnResponse, float> >(); float bestPositivity = 0; foreach (TurnResponse turn in possibleTurns) { BoardState newBoard = InfoGiver.ApplyTurn(board, turn); float positivity = 0; if (depth <= 0) { positivity = LightAnalysis(newBoard.table, team); } else { System.Tuple <TurnResponse, float> recursiveResponse = DeepAnalysis(newBoard, team == Team.A ? Team.B : Team.A, depth - 1); positivity = 1 - recursiveResponse.Item2; } if (isOutputNeeded) { linesToWrite.Add("Depth: " + depth.ToString() + " - Team " + team.ToString() + " - " + turn.cardName + ": (" + turn.source.x + ", " + turn.source.y + ") -> (" + turn.destination.x + ", " + turn.destination.y + ") - Postivity: " + positivity.ToString()); for (int i = 0; i < depth; i++) { linesToWrite.Add(" ---"); } } if (bestPositivity < positivity) { bestTurns = new List <System.Tuple <TurnResponse, float> >(); bestTurns.Add(new System.Tuple <TurnResponse, float>(turn, positivity)); bestPositivity = positivity; } else if (bestPositivity == positivity) { bestTurns.Add(new System.Tuple <TurnResponse, float>(turn, positivity)); } } if (bestTurns.Count == 0) { return(null); } int randomIndex = Random.Range(0, bestTurns.Count); return(bestTurns[randomIndex]); }
private List <TurnResponse> GetAllTurns(BoardState board, Team team) { List <TurnResponse> possibleTurns = new List <TurnResponse>(); PieceState[][] table = board.table; // Making the list of all the moves allowed by card 1; Card card1 = team == Team.A ? board.cardA1 : board.cardB1; int[][] card1MovesTable = team == Team.A ? card1.GetMoves() : card1.GetMovesReversed(); List <Vector2Int> card1Moves = new List <Vector2Int>(); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (card1MovesTable[i][j] == 1) { card1Moves.Add(new Vector2Int(i, j)); } } } // Making the list of all the moves allowed by card 2; Card card2 = team == Team.A ? board.cardA2 : board.cardB2; int[][] card2MovesTable = team == Team.A ? card2.GetMoves() : card2.GetMovesReversed(); List <Vector2Int> card2Moves = new List <Vector2Int>(); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (card2MovesTable[i][j] == 1) { card2Moves.Add(new Vector2Int(i, j)); } } } // Going through the table of the board to find allied pieces and check their possible moves TurnResponse tr = null; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (table[i][j] != null && table[i][j].team == team) { // Going through card1 moves and trying them all foreach (Vector2Int vect in card1Moves) { // At the end of the line, the "-2"s are added to center vect on (2, 2) tr = new TurnResponse(card1.cardName, new Vector2Int(i, j), new Vector2Int(i - 2, j - 2) + vect); if (InfoGiver.IsTurnValid(table, card1, card2, team, tr)) { possibleTurns.Add(tr); } } // Going through card2 moves and trying them all foreach (Vector2Int vect in card2Moves) { // At the end of the line, the "-2"s are added to center vect on (2, 2) tr = new TurnResponse(card2.cardName, new Vector2Int(i, j), new Vector2Int(i - 2, j - 2) + vect); if (InfoGiver.IsTurnValid(table, card1, card2, team, tr)) { possibleTurns.Add(tr); } } } } } return(possibleTurns); }
static void Main(string[] args) { //Class instances InfoGiver infoGive = new InfoGiver(); Checker check = new Checker(); Drawer draw = new Drawer(); //Dynamic arrays cuz i'm cool List <char> usedLetters = new List <char>(); List <char> letter = new List <char>(); //5 lives is good ? int lives = 5; string word; //Games starts and runs while the user wants infoGive.giveUserInfo(); while (true) { Console.WriteLine( "If you quit press Q if you wanna play press any other key!"); ConsoleKeyInfo key = Console.ReadKey(); Console.WriteLine(); if (key.KeyChar == 'Q' || key.KeyChar == 'q') { Console.Clear(); Console.WriteLine("Exiting the game"); Thread.Sleep(1000); break; } else { Console.Clear(); letter.Clear(); usedLetters.Clear(); lives = 5; word = infoGive.generateWords(); letter.AddRange(draw.splitLetter(word)); infoGive.giveWordExplanation(word); while (lives != 0) { Console.Clear(); infoGive.giveWordExplanation(word); draw.writeLives(lives); Console.WriteLine( "Give me a letter"); draw.drawUnderscores(usedLetters, letter); if (!(usedLetters.Count == 0)) { check.checkIfRightGuess(letter); } while (true) { if (check.checkInput(ref usedLetters) == true) { break; } } if (!check.checkIfRightGuess(letter)) { lives--; } if (check.checkIfWordIsGuessed(usedLetters, letter)) { Console.Clear(); draw.drawUnderscores(usedLetters, letter); Console.WriteLine( "And you have guessed the word!"); break; } if (lives == 0) { draw.writeLives(lives); Console.WriteLine( "Sorry endgame"); } } Console.WriteLine(); } } }