Created
December 5, 2024 21:43
-
-
Save justcore69/4b42589579539f3b0c7986219a246c5f to your computer and use it in GitHub Desktop.
AI for a chess-like game "Pawner Likes Fingers"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
// The game is available in browser | |
// https://justcore.itch.io/pawner-likes-fingers | |
public class PawnerAI : MonoBehaviour | |
{ | |
public class PossibleTurn | |
{ | |
public int score; | |
public Cell fromCell; | |
public Cell toCell; | |
public PossibleTurn(Cell from, Cell to, int score) | |
{ | |
fromCell = from; | |
toCell = to; | |
this.score = score; | |
} | |
} | |
public void MakeTurn() | |
{ | |
if (Game.stages.endGame) return; | |
List<PossibleTurn> allTurns = GetAllPossibleTurns(); | |
if (allTurns.Count == 0) | |
{ | |
Debug.Log("Making a null move"); | |
Game.field.MovePawn(null, null); | |
return; | |
} | |
PossibleTurn turn = null; | |
int rand = Random.Range(0, 100); | |
if (rand <= 90) turn = GetBestTurn(allTurns); | |
else if(rand <= 95) turn = GetRandomTurn(allTurns); | |
else turn = GetWorstTurn(allTurns); | |
Game.field.MovePawn(turn.fromCell, turn.toCell); | |
} | |
public PossibleTurn GetBestTurn(List<PossibleTurn> turns) | |
{ | |
int maxScore = 0; | |
List<PossibleTurn> maxTurns = new List<PossibleTurn>(); | |
foreach (var turn in turns) | |
{ | |
if (turn.score > maxScore) maxScore = turn.score; | |
} | |
foreach (var turn in turns) | |
{ | |
if (turn.score == maxScore) maxTurns.Add(turn); | |
} | |
if (maxTurns.Count == 0) return null; | |
return maxTurns[Random.Range(0, maxTurns.Count - 1)]; | |
} | |
public PossibleTurn GetWorstTurn(List<PossibleTurn> turns) | |
{ | |
PossibleTurn minScoreTurn = null; | |
foreach (var turn in turns) | |
{ | |
if (minScoreTurn == null || turn.score < minScoreTurn.score) minScoreTurn = turn; | |
} | |
if (turns.Count == 0) return null; | |
return minScoreTurn; | |
} | |
public PossibleTurn GetRandomTurn(List<PossibleTurn> turns) | |
{ | |
int rand = Random.Range(0, turns.Count - 1); | |
if (turns.Count == 0) return null; | |
return turns[rand]; | |
} | |
private List<PossibleTurn> GetAllPossibleTurns() | |
{ | |
var possibleTurns = new List<PossibleTurn>(); | |
var pawns = GetAllPawnersPawns(); | |
foreach(var pawn in pawns) | |
{ | |
foreach(var cell in pawn.GetPossibleMoves()) | |
{ | |
Vector2 dir = cell.positionInGrid - pawn.cell.positionInGrid; | |
Vector2Int attackDirection = new Vector2Int((int)Mathf.Clamp(dir.x, -1, 1), (int)Mathf.Clamp(dir.y, -1, 1)); | |
Pawn pawnUnderAttack = Game.field.GetPawnAt(cell.positionInGrid + attackDirection); | |
if (pawn.type == Field.PawnType.spear) | |
{ | |
if(pawnUnderAttack != null && pawnUnderAttack.playable) | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 3)); | |
} | |
else if(cell.positionInGrid == new Vector2Int(0, 3) || cell.positionInGrid == new Vector2Int(3, 0)) | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 4)); | |
} | |
else | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 1)); | |
} | |
} | |
else if(pawn.type == Field.PawnType.rock) | |
{ | |
if (Game.field.HasRedPawnAt(cell.positionInGrid + Vector2Int.up)) | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 1)); | |
} | |
else if (cell.positionInGrid == new Vector2Int(Game.field.fieldSize - 2, Game.field.fieldSize - 1) || | |
cell.positionInGrid == new Vector2Int(Game.field.fieldSize - 1, Game.field.fieldSize - 2)) | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 1)); | |
} | |
else | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 0)); | |
} | |
} | |
else if(pawn.type == Field.PawnType.human) | |
{ | |
if (pawnUnderAttack != null && pawnUnderAttack.playable) | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 2)); | |
} | |
else if (cell.positionInGrid == new Vector2Int(0, 2) || cell.positionInGrid == new Vector2Int(2, 0) || cell.positionInGrid == new Vector2Int(2, 2)) | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 3)); | |
} | |
else | |
{ | |
possibleTurns.Add(new PossibleTurn(pawn.cell, cell, 1)); | |
} | |
} | |
} | |
} | |
return possibleTurns; | |
} | |
private List<Pawn> GetAllPawnersPawns() | |
{ | |
var pawnersPawns = new List<Pawn>(); | |
for (int y = 0; y < Game.field.allCells.Length; y++) | |
{ | |
for (int x = 0; x < Game.field.allCells.Length; x++) | |
{ | |
if (Game.field.allCells[y][x].pawn != null && !Game.field.allCells[y][x].pawn.playable) | |
{ | |
pawnersPawns.Add(Game.field.allCells[y][x].pawn); | |
} | |
} | |
} | |
return pawnersPawns; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment