Skip to content

Instantly share code, notes, and snippets.

@justcore69
Created December 5, 2024 21:43
Show Gist options
  • Save justcore69/4b42589579539f3b0c7986219a246c5f to your computer and use it in GitHub Desktop.
Save justcore69/4b42589579539f3b0c7986219a246c5f to your computer and use it in GitHub Desktop.
AI for a chess-like game "Pawner Likes Fingers"
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