fixed stockfish interpretation of smaller and larger boards
This commit is contained in:
parent
401d915a0b
commit
1cce2fe244
9 changed files with 148 additions and 25 deletions
|
|
@ -108,7 +108,15 @@ class ChessEngine extends EventEmitter {
|
|||
this.engine.stdin.write(cmd + '\n');
|
||||
}
|
||||
}
|
||||
async startPos() {
|
||||
if (!this.isReady) throw new Error('Engine not ready');
|
||||
|
||||
this.sendCommand(`position startpos`);
|
||||
|
||||
// Ensure engine is ready after position set
|
||||
this.sendCommand('isready');
|
||||
await new Promise(resolve => this.once('ready', resolve));
|
||||
}
|
||||
async setBoardPosition(fen) {
|
||||
if (!this.isReady) throw new Error('Engine not ready');
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ ffish.onRuntimeInitialized = async () => {
|
|||
engine.sendCommand('setoption name Hash value 128');
|
||||
engine.sendCommand('setoption name MultiPV value 1');
|
||||
engine.sendCommand('setoption name UCI_LimitStrength value true');
|
||||
engine.sendCommand('uci');
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Initialization error:', error);
|
||||
|
|
@ -209,13 +210,10 @@ app.post('/new', async (req, res) => {
|
|||
});
|
||||
|
||||
// Set position endpoint
|
||||
app.post('/position', (req, res) => {
|
||||
app.post('/position', async(req, res) => {
|
||||
lastResponse = new Date().getTime()
|
||||
const { fen, variant = 'chess' } = req.body;
|
||||
const { fen, variant = 'chess', start } = req.body;
|
||||
|
||||
if (!fen) {
|
||||
return res.status(400).json({ error: 'FEN string required' });
|
||||
}
|
||||
|
||||
try {
|
||||
//we have a lot of funky rules lets not validate
|
||||
|
|
@ -232,7 +230,13 @@ app.post('/position', (req, res) => {
|
|||
// // }
|
||||
// board.setFen(fen);
|
||||
// }
|
||||
if(start){
|
||||
await engine.startPos()
|
||||
engine.sendCommand('d');
|
||||
}else if(fen){
|
||||
board.setFen(fen);
|
||||
await engine.setBoardPosition(fen)
|
||||
}
|
||||
|
||||
res.json({
|
||||
status: 'ok',
|
||||
|
|
@ -246,7 +250,7 @@ app.post('/position', (req, res) => {
|
|||
moveStack: board.moveStack()
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
res.status(500).json({ error: error.message, poserr: true });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func connect_to_engine(_path: String, g: ChessGame) -> bool:
|
|||
if ServerManager.is_server_running():
|
||||
print("**************SERVER RUNNING ****************")
|
||||
running = true
|
||||
start_game(2100)
|
||||
# start_game(2100)
|
||||
return true
|
||||
|
||||
await get_tree().create_timer(delay).timeout
|
||||
|
|
@ -74,7 +74,7 @@ func load_fen(fen: String):
|
|||
|
||||
http_request.request(server_url + "/position", headers, HTTPClient.METHOD_POST, body)
|
||||
await http_request.request_completed
|
||||
func start_board(elo: int):
|
||||
func start_board(elo: int, variant: String = "8x8"):
|
||||
if not running:
|
||||
return
|
||||
var headers = ["Content-Type: application/json"]
|
||||
|
|
@ -85,7 +85,7 @@ func start_board(elo: int):
|
|||
print(body)
|
||||
http_request.request(server_url + "/new", headers, HTTPClient.METHOD_POST, body)
|
||||
await http_request.request_completed
|
||||
setElo(elo)
|
||||
setElo(elo, variant)
|
||||
|
||||
func _exit_tree():
|
||||
ServerManager.stop_server()
|
||||
|
|
@ -107,7 +107,40 @@ func get_globalDir() -> String:
|
|||
return OS.get_environment("HOME").path_join("Library/ChessBuilder")
|
||||
|
||||
|
||||
func setElo(elo: int = 1350) -> void:
|
||||
func setVariant(variant: String = "8x8"):
|
||||
if not running:
|
||||
return
|
||||
print("####################################")
|
||||
print("####################################")
|
||||
print("chessbuilder" + variant)
|
||||
print("####################################")
|
||||
print("####################################")
|
||||
print("####################################")
|
||||
var headers = ["Content-Type: application/json"]
|
||||
var data = {
|
||||
"options": [
|
||||
{
|
||||
"name": "VariantPath",
|
||||
"value": get_globalDir() + "/Assets" + "/ChessEngines/Fairy-Stockfish/src/variants.ini"
|
||||
},
|
||||
{
|
||||
"name": "UCI_Variant",
|
||||
"value": "chessbuilder" + variant
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
var body = JSON.new().stringify(data)
|
||||
|
||||
# Request engine move
|
||||
http_request.request(
|
||||
server_url + "/setoptions",
|
||||
headers,
|
||||
HTTPClient.METHOD_POST,
|
||||
body
|
||||
)
|
||||
|
||||
func setElo(elo: int = 1350, variant: String = "8x8") -> void:
|
||||
if not running:
|
||||
return
|
||||
var headers = ["Content-Type: application/json"]
|
||||
|
|
@ -127,7 +160,7 @@ func setElo(elo: int = 1350) -> void:
|
|||
},
|
||||
{
|
||||
"name": "UCI_Variant",
|
||||
"value": "chessbuilder" # Convert int to string
|
||||
"value": "chessbuilder" + variant
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
@ -144,11 +177,18 @@ func setElo(elo: int = 1350) -> void:
|
|||
HTTPClient.METHOD_POST,
|
||||
body
|
||||
)
|
||||
await elo_req.request_completed
|
||||
http_request.request(
|
||||
server_url + "/position",
|
||||
headers,
|
||||
HTTPClient.METHOD_POST,
|
||||
JSON.new().stringify({"start": true})
|
||||
)
|
||||
|
||||
func generateMove(think_time_ms: int = 1000) -> void:
|
||||
if not running:
|
||||
return
|
||||
print("&&&&&&&&&&&&&&&GENERATING MOVE&&&&&&&&&&&&&&&&&&&&&&")
|
||||
print("&&&&&&&&&&&&&&&GENERATING MOVE&&&&&&&&&&&&&&&&&&&&&&", str(game.getCurrentFen()))
|
||||
|
||||
move_time = think_time_ms
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ func _on_new_game_requested(options = {}):
|
|||
cpuElo = options.elo
|
||||
if cameraController:
|
||||
cameraController.reset_view()
|
||||
print("ChessGame FEN ", currentFen)
|
||||
print("ChessGame DIMENSIONS ", get_board_dimensions(currentFen))
|
||||
if is_initialized:
|
||||
resetBoard()
|
||||
initializeDeckSystem()
|
||||
|
|
@ -117,8 +119,10 @@ func _on_new_game_requested(options = {}):
|
|||
stateMachine.transitionToNextState(Constants.WHITE_TURN)
|
||||
else:
|
||||
initialize_game_system()
|
||||
stockfishController.start_board(cpuElo)
|
||||
|
||||
if currentFen:
|
||||
stockfishController.start_board(cpuElo, get_board_dimensions(currentFen))
|
||||
else:
|
||||
stockfishController.start_board(cpuElo, "8x8")
|
||||
func initialize_game_system():
|
||||
print("Initializing game system")
|
||||
# Set up basic styles first
|
||||
|
|
@ -896,3 +900,20 @@ func updateHalfMoveClock(fromIdx: int, toIdx: int) -> void:
|
|||
halfMoveClock = 0
|
||||
else:
|
||||
halfMoveClock += 1
|
||||
|
||||
|
||||
|
||||
func get_board_dimensions(fen_string: String) -> String:
|
||||
var board_part: String = fen_string.split(" ")[0]
|
||||
var ranks: Array = board_part.split("/")
|
||||
var height: int = ranks.size()
|
||||
var width: int = 0
|
||||
var first_rank: String = ranks[0]
|
||||
|
||||
for character in first_rank:
|
||||
if character.is_valid_int():
|
||||
width += int(character)
|
||||
else:
|
||||
width += 1
|
||||
|
||||
return str(width) + "x" + str(height)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ extends Control
|
|||
class_name DeckManagerScreen
|
||||
|
||||
signal back_pressed
|
||||
signal deck_manager_visibility_changed(isvisible)
|
||||
|
||||
# Node references
|
||||
@onready var deckGrid = $MainContainer/GridScrollContainer/GridContainer
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ var max_nodes_per_level = 4
|
|||
var positions_per_level = 6
|
||||
var starting_elo = 1000
|
||||
var final_elo = 2100
|
||||
var current_max_level = 0;
|
||||
# var level_unit_distribution = ["", "", "", "nkr", "rnkr", "rnkbr", "rnqkbr", "rnqkbnr", "rnbqkbnr", "rbnqknbnr", "rnbnqknbnr", "rnbnqknbnbr", "rbnbnqknbnbr"]
|
||||
var level_unit_distribution = ["", "", "nkr", "rnkr", "rnkr", "rnkbr", "rnqkbr", "rnqkbnr", "rnbqkbnr", "rbnqknbnr", "rnbnqknbnr", "rnbnqknbnbr", "rbnbnqknbnbr"]
|
||||
|
||||
var _rng = RandomNumberGenerator.new()
|
||||
var _next_id = 0
|
||||
|
|
@ -29,7 +32,7 @@ func generate_map():
|
|||
_next_id = 0
|
||||
|
||||
var num_levels = _rng.randi_range(min_levels, max_levels)
|
||||
|
||||
current_max_level = num_levels;
|
||||
var elo_step = float(final_elo - starting_elo) / (num_levels - 1)
|
||||
|
||||
var start_node = {
|
||||
|
|
@ -307,10 +310,53 @@ func generate_event_data(node):
|
|||
}
|
||||
# "rnbqkbnr1/pppppppp1/9/9/9/9/9/PPPPPPPP1/RNBQKBNR1 w KQkq - 0 1"
|
||||
func generate_chess_data(node):
|
||||
# level_unit_distribution
|
||||
# current_max_level
|
||||
var rng = float(node.level) / int(current_max_level)
|
||||
var index = map_to_array_index(node.level, 2, current_max_level - 2, 3, level_unit_distribution.size() - 1);
|
||||
var unit_string = level_unit_distribution[index]
|
||||
var pawn_string = ""
|
||||
|
||||
for x in unit_string.length():
|
||||
pawn_string += "p"
|
||||
|
||||
var height = 6;
|
||||
# "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
|
||||
var fen = "";
|
||||
if node.level > 7 and node.level <= 10:
|
||||
height = node.level
|
||||
elif node.level > 10:
|
||||
height = 10
|
||||
for x in height - 2:
|
||||
if x == 0:
|
||||
fen += unit_string + "/"
|
||||
elif x == 1:
|
||||
fen += pawn_string + "/"
|
||||
else:
|
||||
fen += str(unit_string.length()) + "/"
|
||||
|
||||
fen += pawn_string.to_upper() + "/" + unit_string.to_upper()
|
||||
var fen_ending = " w KQkq - 0 1"
|
||||
# print("generate_chess_data ", fen + fen_ending)
|
||||
return {
|
||||
"is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false,
|
||||
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||
"fen": fen + fen_ending,
|
||||
"game_type": "chess",
|
||||
"win_condition": Utils.WinCondition.King,
|
||||
"elo": node.elo,
|
||||
}
|
||||
|
||||
|
||||
func map_to_array_index(current_value, min_value, max_value, min_index, max_index):
|
||||
# Ensure the current value is within bounds
|
||||
var clamped_value = clamp(current_value, min_value, max_value)
|
||||
|
||||
# Calculate how far along the input range we are (0.0 to 1.0)
|
||||
var normalized_position = float(clamped_value - min_value) / float(max_value - min_value)
|
||||
|
||||
# Map this to our target index range
|
||||
var index_range = max_index - min_index
|
||||
var mapped_index = min_index + round(normalized_position * index_range)
|
||||
|
||||
# Ensure we're returning an integer within the valid array index range
|
||||
return int(clamp(mapped_index, min_index, max_index))
|
||||
|
|
|
|||
|
|
@ -38,5 +38,3 @@ func _on_state_delay_timeout() -> void:
|
|||
finished.emit(Constants.HAND_SETUP)
|
||||
func exit() -> void:
|
||||
moveTimer.stop()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,16 +48,19 @@ func enter(_previous: String, _data := {}) -> void:
|
|||
print("GENERATED MOVE ", move)
|
||||
if move:
|
||||
var move_str = move.move # e.g., "e2e4"
|
||||
if "," in move_str:
|
||||
move_str = move.move.split(",")[0]
|
||||
|
||||
var source_square = move_str.substr(0, 2) # "e2"
|
||||
var target_square = move_str.substr(2, 2) # "e4"
|
||||
|
||||
# First select the piece
|
||||
var source_location = Utils.convert_algebraic_to_location(source_square)
|
||||
var source_location = Utils.convert_algebraic_to_location(source_square, game.boardYSize)
|
||||
game.selectedNode = source_location
|
||||
print("source_location ", source_location)
|
||||
|
||||
# Then make the move
|
||||
var target_location = Utils.convert_algebraic_to_location(target_square)
|
||||
var target_location = Utils.convert_algebraic_to_location(target_square, game.boardYSize)
|
||||
print("target_location ", target_location)
|
||||
handleMovement(target_location, true)
|
||||
return
|
||||
|
|
@ -94,8 +97,10 @@ func handleMovement(location: String, generated: bool = false) -> void:
|
|||
var sourceContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer
|
||||
var piece = sourceContainer.get_piece()
|
||||
if piece == null:
|
||||
# print("No Piece")
|
||||
print("No Piece")
|
||||
return
|
||||
else:
|
||||
print("Selected ", piece.name)
|
||||
# print("SColor ", sourcePiece.Item_Color, " tColor ", piece.Item_Color)
|
||||
|
||||
var piece_id = piece.get_instance_id()
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static func generate_guid() -> String:
|
|||
return guid
|
||||
|
||||
|
||||
static func convert_algebraic_to_location(square: String) -> String:
|
||||
static func convert_algebraic_to_location(square: String, maxRank: int) -> String:
|
||||
var file = square[0] # letter (a-h)
|
||||
var rank = int(square[1]) # number (1-8)
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ static func convert_algebraic_to_location(square: String) -> String:
|
|||
# Since we're working with black's moves and our board is oriented with white at bottom:
|
||||
# 1. Flip rank: 8 - rank to mirror vertically
|
||||
file_num = file_num
|
||||
var rank_num = 8 - rank
|
||||
var rank_num = maxRank - rank
|
||||
|
||||
return "%d-%d" % [file_num, rank_num]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue