added dynamic variant creation and unit definition for better special movement response by stockfish
This commit is contained in:
parent
860c3d31a7
commit
e74f767cdb
11 changed files with 390 additions and 14 deletions
|
|
@ -9,7 +9,7 @@ func _init():
|
||||||
description = "Attached Unit can move and capture in any direction"
|
description = "Attached Unit can move and capture in any direction"
|
||||||
duration = 3
|
duration = 3
|
||||||
unitWhitelist = ["Pawn", "Bishop", "Queen", "Rook", "King"]
|
unitWhitelist = ["Pawn", "Bishop", "Queen", "Rook", "King"]
|
||||||
is_default = true
|
is_default = false
|
||||||
# current_movement_string = "mWmFcfF"
|
# current_movement_string = "mWmFcfF"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ func _init():
|
||||||
rank = Rank.RANK_2
|
rank = Rank.RANK_2
|
||||||
effectType = EffectType.MOVEMENT_MODIFIER
|
effectType = EffectType.MOVEMENT_MODIFIER
|
||||||
description = "Attached Pawn can move and capture in any direction"
|
description = "Attached Pawn can move and capture in any direction"
|
||||||
duration = 1 # Lasts for 2 turns
|
duration = 3
|
||||||
unitWhitelist = ["Pawn"]
|
unitWhitelist = ["Pawn"]
|
||||||
is_default = false
|
is_default = false
|
||||||
# current_movement_string = "mWmFcfF"
|
# current_movement_string = "mWmFcfF"
|
||||||
|
|
@ -24,5 +24,5 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null):
|
||||||
|
|
||||||
func reset():
|
func reset():
|
||||||
super.reset()
|
super.reset()
|
||||||
remaining_turns = duration
|
remaining_turns = duration
|
||||||
attached_piece.reset_current_movement_string()
|
attached_piece.reset_current_movement_string()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ func _init():
|
||||||
rank = Rank.RANK_3
|
rank = Rank.RANK_3
|
||||||
effectType = EffectType.MOVEMENT_MODIFIER
|
effectType = EffectType.MOVEMENT_MODIFIER
|
||||||
description = "Attached Pawn can move in any direction, can only capture diagonally forward"
|
description = "Attached Pawn can move in any direction, can only capture diagonally forward"
|
||||||
duration = 1 # Lasts for 2 turns
|
duration = 4
|
||||||
unitWhitelist = ["Pawn"]
|
unitWhitelist = ["Pawn"]
|
||||||
is_default = true
|
is_default = true
|
||||||
# current_movement_string = "mWmFcfF"
|
# current_movement_string = "mWmFcfF"
|
||||||
|
|
|
||||||
286
Systems/FairyStockfish/FairyStockfishVariantGenerator.gd
Normal file
286
Systems/FairyStockfish/FairyStockfishVariantGenerator.gd
Normal file
|
|
@ -0,0 +1,286 @@
|
||||||
|
extends Node
|
||||||
|
class_name FairyStockfishVariantGenerator
|
||||||
|
|
||||||
|
const STANDARD_PIECE_CHARS = "PNBRQK"
|
||||||
|
const files = "abcdefghijkl"
|
||||||
|
const VARIANT_CHARS = "ACDEFGHIJLMOSTVWXYZ"
|
||||||
|
|
||||||
|
func generate_variant_string(chess_game: ChessGame) -> String:
|
||||||
|
var width = chess_game.boardXSize
|
||||||
|
var height = chess_game.boardYSize
|
||||||
|
var prefix = "chessbuilder" + str(width) + "x" + str(height)
|
||||||
|
|
||||||
|
var piece_data = gather_piece_data(chess_game)
|
||||||
|
var piece_definitions = piece_data.definitions
|
||||||
|
var piece_mappings = piece_data.mappings
|
||||||
|
var used_variant_chars = piece_data.used_chars
|
||||||
|
|
||||||
|
var variant_string = "[" + prefix + ":chess]\n"
|
||||||
|
|
||||||
|
# Build the pieceToCharTable with all used variant characters
|
||||||
|
var char_table = build_piece_char_table(used_variant_chars)
|
||||||
|
variant_string += "pieceToCharTable = " + char_table + "\n"
|
||||||
|
|
||||||
|
variant_string += "maxRank = " + str(height) + "\n"
|
||||||
|
variant_string += "maxFile = " + files[width - 1] + "\n"
|
||||||
|
|
||||||
|
var current_fen = chess_game.getCurrentFen()
|
||||||
|
variant_string += "startFen = " + current_fen + "\n\n"
|
||||||
|
|
||||||
|
# Add wall types
|
||||||
|
variant_string += "walltype = * # Duck wall\n"
|
||||||
|
variant_string += "walltype = @ # Stone wall\n\n"
|
||||||
|
|
||||||
|
# Add walling rules
|
||||||
|
variant_string += "wallingRule = static\n"
|
||||||
|
variant_string += "wallOrMove = false\n"
|
||||||
|
variant_string += "mobilityRegion = *:@\n"
|
||||||
|
variant_string += "prohibitedMove = *@\n\n"
|
||||||
|
|
||||||
|
# Add the piece definitions
|
||||||
|
variant_string += "# Custom piece movement definitions\n"
|
||||||
|
for piece_key in piece_definitions:
|
||||||
|
variant_string += "piece " + piece_key + " = " + piece_definitions[piece_key] + "\n"
|
||||||
|
|
||||||
|
# Add pieceDrops if needed for capturing
|
||||||
|
variant_string += "\n# Allow capturing with custom pieces\n"
|
||||||
|
variant_string += "pieceDrops = true\n"
|
||||||
|
|
||||||
|
return variant_string
|
||||||
|
|
||||||
|
# Build a complete pieceToCharTable that includes all variant characters
|
||||||
|
func build_piece_char_table(used_variant_chars: Array) -> String:
|
||||||
|
var char_table = STANDARD_PIECE_CHARS
|
||||||
|
|
||||||
|
for variant_char in used_variant_chars:
|
||||||
|
char_table += variant_char.to_upper()
|
||||||
|
|
||||||
|
char_table += "..*@..........."
|
||||||
|
|
||||||
|
# Add lowercase versions
|
||||||
|
char_table += STANDARD_PIECE_CHARS.to_lower()
|
||||||
|
|
||||||
|
for variant_char in used_variant_chars:
|
||||||
|
char_table += variant_char.to_lower()
|
||||||
|
|
||||||
|
char_table += "..*@..........."
|
||||||
|
|
||||||
|
return char_table
|
||||||
|
|
||||||
|
# Gather all piece data from the current game state
|
||||||
|
func gather_piece_data(chess_game: ChessGame) -> Dictionary:
|
||||||
|
# Dictionary to track unique movement patterns
|
||||||
|
# Key format: "piece_char:color:movement_string"
|
||||||
|
var unique_movements = {}
|
||||||
|
|
||||||
|
var modified_piece_types = {}
|
||||||
|
|
||||||
|
# First pass: collect all unique movement patterns
|
||||||
|
for y in range(chess_game.boardYSize):
|
||||||
|
for x in range(chess_game.boardXSize):
|
||||||
|
var container = chess_game.boardContainer.get_node(str(x) + "-" + str(y)) as PieceContainer
|
||||||
|
if container && container.has_piece():
|
||||||
|
var piece = container.get_piece() as Pawn
|
||||||
|
|
||||||
|
if piece.current_movement_string != piece.original_movement_string:
|
||||||
|
var piece_char = get_piece_char(piece)
|
||||||
|
var color_key = "white" if piece.Item_Color == 0 else "black"
|
||||||
|
var piece_key = piece_char + ":" + color_key
|
||||||
|
|
||||||
|
if !modified_piece_types.has(piece_key):
|
||||||
|
modified_piece_types[piece_key] = true
|
||||||
|
|
||||||
|
var movement_key = piece_key + ":" + piece.current_movement_string
|
||||||
|
|
||||||
|
if !unique_movements.has(movement_key):
|
||||||
|
unique_movements[movement_key] = {
|
||||||
|
"piece_char": piece_char,
|
||||||
|
"color": color_key,
|
||||||
|
"betza_notation": piece.current_movement_string,
|
||||||
|
"fairy_notation": convert_betza_to_fairy_stockfish(piece.current_movement_string),
|
||||||
|
"positions": []
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_movements[movement_key].positions.append(str(x) + "-" + str(y))
|
||||||
|
|
||||||
|
var variant_char_index = 0
|
||||||
|
var piece_definitions = {}
|
||||||
|
var piece_mappings = {}
|
||||||
|
var used_variant_chars = []
|
||||||
|
|
||||||
|
for movement_key in unique_movements:
|
||||||
|
var movement_data = unique_movements[movement_key]
|
||||||
|
var piece_char = movement_data.piece_char
|
||||||
|
var color = movement_data.color
|
||||||
|
var fs_notation = movement_data.fairy_notation
|
||||||
|
|
||||||
|
var variant_char
|
||||||
|
if variant_char_index < VARIANT_CHARS.length():
|
||||||
|
variant_char = VARIANT_CHARS[variant_char_index]
|
||||||
|
used_variant_chars.append(variant_char)
|
||||||
|
variant_char_index += 1
|
||||||
|
else:
|
||||||
|
# If we run out of variant chars, we'll need to add more or implement another solution
|
||||||
|
print("Warning: Ran out of variant characters for piece definitions")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Store the piece definition
|
||||||
|
var definition_key = variant_char.to_upper() if color == "white" else variant_char.to_lower()
|
||||||
|
piece_definitions[definition_key] = fs_notation
|
||||||
|
|
||||||
|
for pos in movement_data.positions:
|
||||||
|
piece_mappings[pos] = definition_key
|
||||||
|
|
||||||
|
return {
|
||||||
|
"definitions": piece_definitions,
|
||||||
|
"mappings": piece_mappings,
|
||||||
|
"used_chars": used_variant_chars
|
||||||
|
}
|
||||||
|
|
||||||
|
func get_piece_char(piece: Pawn) -> String:
|
||||||
|
match piece.name:
|
||||||
|
"Pawn": return "P"
|
||||||
|
"Knight": return "N"
|
||||||
|
"Bishop": return "B"
|
||||||
|
"Rook": return "R"
|
||||||
|
"Queen": return "Q"
|
||||||
|
"King": return "K"
|
||||||
|
_: return "P" # Default to pawn
|
||||||
|
|
||||||
|
func convert_betza_to_fairy_stockfish(betza_notation: String) -> String:
|
||||||
|
var atoms = parse_betza_notation(betza_notation)
|
||||||
|
var fairy_stockfish_moves = []
|
||||||
|
|
||||||
|
for atom in atoms:
|
||||||
|
var move_type = atom.type
|
||||||
|
var modifiers = atom.modifiers
|
||||||
|
var range_limit = atom.range
|
||||||
|
|
||||||
|
var move_only = "m" in modifiers
|
||||||
|
var capture_only = "c" in modifiers
|
||||||
|
|
||||||
|
# Process direction modifiers
|
||||||
|
var direction_modifiers = []
|
||||||
|
for modifier in modifiers:
|
||||||
|
if modifier.length() > 1 || ["f", "b", "l", "r"].has(modifier):
|
||||||
|
for char in modifier:
|
||||||
|
if ["f", "b", "l", "r"].has(char):
|
||||||
|
direction_modifiers.append(char)
|
||||||
|
|
||||||
|
var fs_move = ""
|
||||||
|
|
||||||
|
match move_type:
|
||||||
|
"W": fs_move += "W" # Wazir (orthogonal step)
|
||||||
|
"F": fs_move += "F" # Ferz (diagonal step)
|
||||||
|
"R": fs_move += "R" # Rook (orthogonal slider)
|
||||||
|
"B": fs_move += "B" # Bishop (diagonal slider)
|
||||||
|
"N": fs_move += "N" # Knight
|
||||||
|
"K": fs_move += "K" # King (one step in any direction)
|
||||||
|
"Q": fs_move += "Q" # Queen (combination of R and B)
|
||||||
|
|
||||||
|
if range_limit > 0:
|
||||||
|
fs_move += str(range_limit)
|
||||||
|
|
||||||
|
if direction_modifiers.size() > 0:
|
||||||
|
fs_move += "/"
|
||||||
|
for dir in direction_modifiers:
|
||||||
|
match dir:
|
||||||
|
"f": fs_move += "f"
|
||||||
|
"b": fs_move += "b"
|
||||||
|
"l": fs_move += "l"
|
||||||
|
"r": fs_move += "r"
|
||||||
|
|
||||||
|
if move_only:
|
||||||
|
fs_move += "m"
|
||||||
|
elif capture_only:
|
||||||
|
fs_move += "c"
|
||||||
|
|
||||||
|
fairy_stockfish_moves.append(fs_move)
|
||||||
|
var ret_str = ""
|
||||||
|
for moves in fairy_stockfish_moves:
|
||||||
|
ret_str += str(moves) + " "
|
||||||
|
|
||||||
|
return ret_str
|
||||||
|
|
||||||
|
# Parse Betza notation into atoms
|
||||||
|
func parse_betza_notation(notation: String) -> Array:
|
||||||
|
var atoms = []
|
||||||
|
var i = 0
|
||||||
|
|
||||||
|
while i < notation.length():
|
||||||
|
var atom = {
|
||||||
|
"type": "",
|
||||||
|
"modifiers": [],
|
||||||
|
"range": -1 # -1 means unlimited
|
||||||
|
}
|
||||||
|
|
||||||
|
while i < notation.length() && ["m", "c"].has(notation[i]):
|
||||||
|
atom.modifiers.append(notation[i])
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
var directions = ""
|
||||||
|
while i < notation.length() && ["f", "b", "l", "r"].has(notation[i]):
|
||||||
|
directions += notation[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if directions:
|
||||||
|
atom.modifiers.append(directions)
|
||||||
|
|
||||||
|
# Get the atom type
|
||||||
|
if i < notation.length():
|
||||||
|
atom.type = notation[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# Check for range specification
|
||||||
|
var range_str = ""
|
||||||
|
while i < notation.length() && notation[i].is_valid_int():
|
||||||
|
range_str += notation[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if range_str:
|
||||||
|
atom.range = int(range_str)
|
||||||
|
|
||||||
|
atoms.append(atom)
|
||||||
|
|
||||||
|
return atoms
|
||||||
|
|
||||||
|
# Generate a modified FEN string with custom piece characters
|
||||||
|
func generate_modified_fen(chess_game: ChessGame, piece_mappings: Dictionary) -> String:
|
||||||
|
var fen_parts = chess_game.getCurrentFen().split(" ")
|
||||||
|
var board_part = fen_parts[0]
|
||||||
|
var rows = board_part.split("/")
|
||||||
|
var new_rows = []
|
||||||
|
|
||||||
|
for y in range(rows.size()):
|
||||||
|
var new_row = ""
|
||||||
|
var x = 0
|
||||||
|
|
||||||
|
for c in rows[y]:
|
||||||
|
if c.is_valid_int():
|
||||||
|
# Handle empty squares
|
||||||
|
new_row += c
|
||||||
|
x += int(c)
|
||||||
|
else:
|
||||||
|
var pos = str(x) + "-" + str(y)
|
||||||
|
if piece_mappings.has(pos):
|
||||||
|
new_row += piece_mappings[pos]
|
||||||
|
else:
|
||||||
|
new_row += c
|
||||||
|
x += 1
|
||||||
|
|
||||||
|
new_rows.append(new_row)
|
||||||
|
|
||||||
|
fen_parts[0] = new_rows.join("/")
|
||||||
|
return fen_parts.join(" ")
|
||||||
|
|
||||||
|
# Save the variant definition to a file
|
||||||
|
func save_variant_to_file(variant_string: String) -> bool:
|
||||||
|
print("VARIANT ", variant_string)
|
||||||
|
ServerManager.write_variant(variant_string)
|
||||||
|
return true
|
||||||
|
|
||||||
|
# Helper function to get a complete variant definition for the current game state
|
||||||
|
func generate_and_save_variant(chess_game: ChessGame) -> String:
|
||||||
|
var variant_string = generate_variant_string(chess_game)
|
||||||
|
save_variant_to_file(variant_string)
|
||||||
|
return variant_string
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://boryt6vnd0icx
|
||||||
|
|
@ -3,6 +3,7 @@ extends Node
|
||||||
|
|
||||||
var server_path: String = ""
|
var server_path: String = ""
|
||||||
var log_dir: String = ""
|
var log_dir: String = ""
|
||||||
|
var variant_dir : String = ""
|
||||||
var log_string: String = ""
|
var log_string: String = ""
|
||||||
var running := false
|
var running := false
|
||||||
var server_process_id: int = -50
|
var server_process_id: int = -50
|
||||||
|
|
@ -12,6 +13,29 @@ var ping_http: HTTPRequest
|
||||||
|
|
||||||
var server_url = "http://localhost:27531"
|
var server_url = "http://localhost:27531"
|
||||||
|
|
||||||
|
|
||||||
|
func write_variant(variant_string: String):
|
||||||
|
|
||||||
|
var file = FileAccess.open(variant_dir, FileAccess.WRITE_READ)
|
||||||
|
var error = FileAccess.get_open_error()
|
||||||
|
|
||||||
|
if error != OK:
|
||||||
|
# print("Failed to open log file. Error code: ", error)
|
||||||
|
return
|
||||||
|
|
||||||
|
if file == null:
|
||||||
|
# print("File handle is null")
|
||||||
|
return
|
||||||
|
|
||||||
|
file.store_string(variant_string)
|
||||||
|
|
||||||
|
var write_error = FileAccess.get_open_error()
|
||||||
|
if write_error != OK:
|
||||||
|
print("Failed to write to log file. Error code: ", write_error)
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
func write_log(message: String):
|
func write_log(message: String):
|
||||||
# First check if path is valid
|
# First check if path is valid
|
||||||
# print("Attempting to write to: ", log_dir)
|
# print("Attempting to write to: ", log_dir)
|
||||||
|
|
@ -41,6 +65,7 @@ func write_log(message: String):
|
||||||
func _ready():
|
func _ready():
|
||||||
server_path = extract_server_files() + "/ChessEngines/fairy-chess-server"
|
server_path = extract_server_files() + "/ChessEngines/fairy-chess-server"
|
||||||
setup_logging()
|
setup_logging()
|
||||||
|
setup_variant()
|
||||||
check_server_files(server_path)
|
check_server_files(server_path)
|
||||||
start_server()
|
start_server()
|
||||||
get_tree().set_auto_accept_quit(false)
|
get_tree().set_auto_accept_quit(false)
|
||||||
|
|
@ -117,6 +142,14 @@ func setup_logging():
|
||||||
|
|
||||||
log_dir = l_dir.path_join("godot-chess.log")
|
log_dir = l_dir.path_join("godot-chess.log")
|
||||||
write_log("ServerManager initialized")
|
write_log("ServerManager initialized")
|
||||||
|
func setup_variant():
|
||||||
|
var l_dir = get_globalDir() + "/variant"
|
||||||
|
|
||||||
|
# Create directory if it doesn't exist
|
||||||
|
DirAccess.make_dir_recursive_absolute(l_dir)
|
||||||
|
|
||||||
|
variant_dir = l_dir.path_join("custom_variant.ini")
|
||||||
|
write_log("ServerManager Variants initialized")
|
||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
stop_server()
|
stop_server()
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,6 @@ func _exit_tree():
|
||||||
disconnect_engine();
|
disconnect_engine();
|
||||||
|
|
||||||
|
|
||||||
func update_position(fen: String):
|
|
||||||
load_fen(fen)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -121,7 +119,7 @@ func setVariant(variant: String = "8x8"):
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"name": "VariantPath",
|
"name": "VariantPath",
|
||||||
"value": get_globalDir() + "/Assets" + "/ChessEngines/Fairy-Stockfish/src/variants.ini"
|
"value": get_globalDir() + "/variant" + "/custom_variant.ini"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UCI_Variant",
|
"name": "UCI_Variant",
|
||||||
|
|
@ -148,7 +146,7 @@ func setElo(elo: int = 1350, variant: String = "8x8") -> void:
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"name": "VariantPath",
|
"name": "VariantPath",
|
||||||
"value": get_globalDir() + "/Assets" + "/ChessEngines/Fairy-Stockfish/src/variants.ini"
|
"value": get_globalDir() + "/variant" + "/custom_variant.ini"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "UCI_LimitStrength",
|
"name": "UCI_LimitStrength",
|
||||||
|
|
@ -188,7 +186,7 @@ func setElo(elo: int = 1350, variant: String = "8x8") -> void:
|
||||||
func generateMove(think_time_ms: int = 1000) -> void:
|
func generateMove(think_time_ms: int = 1000) -> void:
|
||||||
if not running:
|
if not running:
|
||||||
return
|
return
|
||||||
print("&&&&&&&&&&&&&&&GENERATING MOVE&&&&&&&&&&&&&&&&&&&&&&", str(game.getCurrentFen()))
|
print("&&&&&&&&&&&&&&&GENERATING MOVE&&&&&&&&&&&&&&&&&&&&&&", str(game.generate_variant_aware_fen()))
|
||||||
|
|
||||||
move_time = think_time_ms
|
move_time = think_time_ms
|
||||||
|
|
||||||
|
|
@ -196,7 +194,7 @@ func generateMove(think_time_ms: int = 1000) -> void:
|
||||||
var body = JSON.stringify({
|
var body = JSON.stringify({
|
||||||
"movetime": think_time_ms,
|
"movetime": think_time_ms,
|
||||||
"depth": 15,
|
"depth": 15,
|
||||||
"fen": str(game.getCurrentFen())
|
"fen": str(game.generate_variant_aware_fen())
|
||||||
})
|
})
|
||||||
|
|
||||||
# Request engine move
|
# Request engine move
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ var winConditionManager: WinConditionManager = null
|
||||||
var boss_type = null
|
var boss_type = null
|
||||||
var boss_turn_additional = null
|
var boss_turn_additional = null
|
||||||
var boss_turn_index = null
|
var boss_turn_index = null
|
||||||
|
var fairyStockfishVariantGenerator = FairyStockfishVariantGenerator.new()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -153,6 +154,7 @@ func _on_new_game_requested(options = {}):
|
||||||
initializeDeckSystem(mode == "vanilla")
|
initializeDeckSystem(mode == "vanilla")
|
||||||
initializeBoard()
|
initializeBoard()
|
||||||
initializeTiles()
|
initializeTiles()
|
||||||
|
fairyStockfishVariantGenerator.generate_and_save_variant(self)
|
||||||
if cardDisplay:
|
if cardDisplay:
|
||||||
cardDisplay.visible = true
|
cardDisplay.visible = true
|
||||||
if stateMachine:
|
if stateMachine:
|
||||||
|
|
@ -160,6 +162,7 @@ func _on_new_game_requested(options = {}):
|
||||||
stateMachine.transitionToNextState(Constants.BLACK_TURN)
|
stateMachine.transitionToNextState(Constants.BLACK_TURN)
|
||||||
else:
|
else:
|
||||||
initialize_game_system(mode == "vanilla")
|
initialize_game_system(mode == "vanilla")
|
||||||
|
fairyStockfishVariantGenerator.generate_and_save_variant(self)
|
||||||
if currentFen:
|
if currentFen:
|
||||||
stockfishController.start_board(cpuElo, get_board_dimensions(currentFen))
|
stockfishController.start_board(cpuElo, get_board_dimensions(currentFen))
|
||||||
else:
|
else:
|
||||||
|
|
@ -903,8 +906,60 @@ func parseLocation(location: String) -> void:
|
||||||
number += 1
|
number += 1
|
||||||
locationY = location.substr(number + 1)
|
locationY = location.substr(number + 1)
|
||||||
|
|
||||||
|
func generate_variant_aware_fen() -> String:
|
||||||
|
var piece_data = fairyStockfishVariantGenerator.gather_piece_data(self)
|
||||||
|
var piece_mappings = piece_data.mappings
|
||||||
|
|
||||||
|
var fen = ""
|
||||||
|
|
||||||
|
for y in range(boardYSize):
|
||||||
|
var emptySquares = 0
|
||||||
|
for x in range(boardXSize):
|
||||||
|
var container = boardContainer.get_node(str(x) + "-" + str(y)) as PieceContainer
|
||||||
|
var pos_key = str(x) + "-" + str(y)
|
||||||
|
|
||||||
|
if tileManager.active_tiles.has(pos_key):
|
||||||
|
var tile = tileManager.active_tiles[pos_key]
|
||||||
|
if tile is WallTile or tile is DoubleWallTile:
|
||||||
|
if emptySquares > 0:
|
||||||
|
fen += str(emptySquares)
|
||||||
|
emptySquares = 0
|
||||||
|
fen += "*" # Wall character
|
||||||
|
continue
|
||||||
|
elif tile is PortalTile:
|
||||||
|
pass
|
||||||
|
|
||||||
|
var piece = container.get_piece()
|
||||||
|
if piece == null:
|
||||||
|
emptySquares += 1
|
||||||
|
else:
|
||||||
|
if emptySquares > 0:
|
||||||
|
fen += str(emptySquares)
|
||||||
|
emptySquares = 0
|
||||||
|
|
||||||
|
if piece_mappings.has(pos_key):
|
||||||
|
fen += piece_mappings[pos_key]
|
||||||
|
else:
|
||||||
|
fen += getPieceFenChar(piece)
|
||||||
|
|
||||||
|
if emptySquares > 0:
|
||||||
|
fen += str(emptySquares)
|
||||||
|
|
||||||
|
if y < boardYSize - 1:
|
||||||
|
fen += "/"
|
||||||
|
|
||||||
|
fen += " %s %s %s %d %d" % [
|
||||||
|
"b" if currentPlayer == BLACK else "w",
|
||||||
|
castlingRights,
|
||||||
|
enPassantTarget,
|
||||||
|
halfMoveClock,
|
||||||
|
moveCount
|
||||||
|
]
|
||||||
|
|
||||||
|
return fen
|
||||||
|
|
||||||
|
|
||||||
func getCurrentFen() -> String:
|
func getCurrentFen() -> String:
|
||||||
# Generate FEN string from the current board position
|
|
||||||
var fen = ""
|
var fen = ""
|
||||||
|
|
||||||
# For a standard chess board, we want to generate FEN from top (black side, rank 8)
|
# For a standard chess board, we want to generate FEN from top (black side, rank 8)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ extends Control
|
||||||
class_name ProgressionScreen
|
class_name ProgressionScreen
|
||||||
|
|
||||||
signal save_pressed
|
signal save_pressed
|
||||||
signal deck_manager_visibility_changed(isvisible)
|
signal progression_screen_visibility_changed(isvisible)
|
||||||
|
|
||||||
@onready var deckGrid = $MainContainer/GridScrollContainer/GridContainer
|
@onready var deckGrid = $MainContainer/GridScrollContainer/GridContainer
|
||||||
@onready var bankContainer = $MainContainer/BankContainer/ScrollContainer/VBoxContainer
|
@onready var bankContainer = $MainContainer/BankContainer/ScrollContainer/VBoxContainer
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ func enter(_previous: String, _data := {}) -> void:
|
||||||
print("ENTERING STATE ", Constants.BLACK_TURN)
|
print("ENTERING STATE ", Constants.BLACK_TURN)
|
||||||
game.currentPlayer = game.BLACK
|
game.currentPlayer = game.BLACK
|
||||||
game.updateTurnIndicator()
|
game.updateTurnIndicator()
|
||||||
|
var variant = game.get_board_dimensions(game.currentFen)
|
||||||
|
game.stockfishController.setVariant(variant)
|
||||||
# Delay to avoid duplication during animation
|
# Delay to avoid duplication during animation
|
||||||
if game.stockfishController:
|
if game.stockfishController:
|
||||||
moveTimer.start(2)
|
moveTimer.start(2)
|
||||||
|
|
@ -29,7 +30,7 @@ func _on_move_timer_timeout() -> void:
|
||||||
if game.stockfishController:
|
if game.stockfishController:
|
||||||
print("------------------STARTING GENERATING MOVE --------------------")
|
print("------------------STARTING GENERATING MOVE --------------------")
|
||||||
|
|
||||||
game.stockfishController.load_fen(game.getCurrentFen())
|
game.stockfishController.load_fen(game.generate_variant_aware_fen())
|
||||||
OS.delay_msec(250)
|
OS.delay_msec(250)
|
||||||
game.stockfishController.generateMove(1000) # 1 second think time
|
game.stockfishController.generateMove(1000) # 1 second think time
|
||||||
stateDelay.start(2)
|
stateDelay.start(2)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ func enter(_previous: String, data := {}) -> void:
|
||||||
|
|
||||||
|
|
||||||
if game.currentPlayer == game.WHITE and game.has_opponent:
|
if game.currentPlayer == game.WHITE and game.has_opponent:
|
||||||
|
var variant_file = game.fairyStockfishVariantGenerator.generate_and_save_variant(game)
|
||||||
|
# print("Variant Generated ", variant_file)
|
||||||
finished.emit(Constants.BLACK_TURN)
|
finished.emit(Constants.BLACK_TURN)
|
||||||
else:
|
else:
|
||||||
finished.emit(Constants.WHITE_TURN)
|
finished.emit(Constants.WHITE_TURN)
|
||||||
Loading…
Reference in a new issue