Closed Nexoduck198 closed 1 year ago
Please show ur code btw. But my best guess would be that you're using a global Move variable which causes all sorts of issues
Heres my code (also what do you mean by global Move? a bit new to coding)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
struct MoveEval
{
public Move move = new Move();
public int eval;
public MoveEval (Move m, int val)
{
move = m;
eval = val;
}
}
//latrunculorum
public class MyBot : IChessBot
{
int prevMovesCount = 2;
// Piece values: null, pawn, horsie, bishop, rook, queen, king
List<Square> prevMoves = new List<Square>();
int[] pieceValues = { 0, 100, 300, 300, 500, 900, 10000 };
Board board;
Move bestMove;
/*
* Note: 3900 = total amount of points on a starting board
*
* Range of of points for pieces to start moving
* Pieces won't move if the value is above the min
* and won't be affected if below the max
* kinda reversed
*
* Ex:
* 0 Move | | | 1000 | | Dont move | | | 3900
*/
//P.s. valu must be within 0 - 3900
int[][] pieceMoveRange = new int[][]
{
new int [] { 3700, 3950 }, //Horsie
new int [] { 3700, 3950 }, //Bishop
new int [] { 3000, 3700 }, //Rook
new int [] { 3400, 3700 }, //Queen
new int [] { 1000, 2000 } //King
};
//Max amount of Discourage
public Move Think(Board b, Timer timer)
{
board = b;
Move[] allMoves = board.GetLegalMoves();
// Pick a random move to play if nothing better is found
Random rng = new();
bestMove = allMoves[rng.Next(allMoves.Length)];
int highestEval = 0;
foreach (Move move in allMoves)
{
int eval = EvaluateGuess(move);
if (eval > highestEval)
{
Console.WriteLine("**Best Move: " + move + " : " + eval + "** \n");
bestMove = move;
highestEval = eval;
}
board.UndoMove(move);
}
prevMoves.Add(bestMove.StartSquare);
if(prevMoves.Count > prevMovesCount)
{
prevMoves.RemoveAt(prevMovesCount - 1);
}
return bestMove;
}
/* int Search(int depth, int alpha, int beta)
{
}*/
/*
int Search(int depth, bool isWhite)
{
//Console.WriteLine(move + " : depth-" + depth + " : eval-" + Evaluate(isWhite));
if (depth <= 0)
{
return Evaluate(isWhite);
}
Move[] moves = board.GetLegalMoves();
int maxEval = int.MinValue;
int minEval = int.MaxValue;
int eval = 0;
if(isWhite)
{
for (int i = 0; i < moves.Length; i++)
{
board.MakeMove(moves[i]);
eval = -Search(depth - 1, false);
if(eval > maxEval)
{
maxEval = eval;
}
board.UndoMove(moves[i]);
}
return maxEval;
}
else
{
for (int i = 0; i < moves.Length; i++)
{
board.MakeMove(moves[i]);
eval = -Search(depth - 1, true);
if(eval < minEval)
{
minEval = eval;
}
board.UndoMove(moves[i]);
}
return minEval;
}
}
*/
int Evaluate()
{
int whiteEval = CountMaterial(true);
int blackEval = CountMaterial(false);
int evaluation = whiteEval - blackEval;
int perception = board.IsWhiteToMove ? 1 : -1;
return evaluation * perception;
}
//Evaluate with additional modifiers
//ex. not sacking its pieces
int EvaluateGuess(Move move)
{
double evalMod = 0;
//Makes pieces want to move more depending on the pieces left on the board
int max = 0;
int min = 0;
switch (move.MovePieceType)
{
case PieceType.Pawn:
min = 3990;
max = 4000;
break;
case PieceType.Knight:
max = pieceMoveRange[0][1];
min = pieceMoveRange[0][0];
break;
case PieceType.Bishop:
max = pieceMoveRange[1][1];
min = pieceMoveRange[1][0];
break;
case PieceType.Rook:
max = pieceMoveRange[2][1];
min = pieceMoveRange[2][0];
break;
case PieceType.Queen:
max = pieceMoveRange[3][1];
min = pieceMoveRange[3][0];
break;
case PieceType.King:
max = pieceMoveRange[4][1];
min = pieceMoveRange[4][0];
break;
}
double discouragePercent = (Math.Clamp(CountMaterial(board.IsWhiteToMove), min, max) - min) / (max - min);
//Discourages sacking pieces
if (board.SquareIsAttackedByOpponent(move.TargetSquare))
{
evalMod -= pieceValues[(int)move.MovePieceType];
}
board.MakeMove(move);
//IsSquareAttacked(BitboardHelper.GetPawnAttacks(move.StartSquare, board.IsWhiteToMove));
// Always play checkmate in one
if (board.IsInCheckmate())
{
evalMod += 99999;
}
//Prioritize checks using lower value pieces
if (board.IsInCheck())
{
evalMod += Math.Clamp(1000 - pieceValues[(int)move.MovePieceType], 150, 1000);
}
//Encourages moving in protected squares
if (board.SquareIsAttackedByOpponent(move.TargetSquare))
{
evalMod += Math.Clamp(pieceValues[(int)move.MovePieceType], 100, 600);
}
if (prevMoves.Count > 0)
{
if (prevMoves.Contains(move.TargetSquare))
{
evalMod *= .3;
}
}
Console.WriteLine(move + " : " + Evaluate() + "** \n");
board.UndoMove(move);
//Discourages moves late game/early game depending on the piece type
evalMod *= (1 - discouragePercent) + .2;
return Evaluate() + (int)evalMod;
}
int CountMaterial(bool isWhite)
{
int material = 0;
material += board.GetPieceList(PieceType.Pawn, isWhite).Count * pieceValues[1];
material += board.GetPieceList(PieceType.Knight, isWhite).Count * pieceValues[2];
material += board.GetPieceList(PieceType.Bishop, isWhite).Count * pieceValues[3];
material += board.GetPieceList(PieceType.Rook, isWhite).Count * pieceValues[4];
material += board.GetPieceList(PieceType.Queen, isWhite).Count * pieceValues[5];
return material;
}
bool IsSquareAttacked(ulong bitboard)
{
// Console.WriteLine(bitboard);
return false;
}
}```
Nevermind, turns out it was a lone UndoMove
Have been getting an error whenever I let my bot play agaisnt evil bot for a while