Files
prosperon/examples/chess/client.ce
2026-02-25 22:13:42 -06:00

167 lines
4.5 KiB
Plaintext

var core = use('core')
var camera = use('camera')
var compositor = use('compositor')
var input = use('input')
var Grid = use('examples/chess/grid')
var rules = use('examples/chess/rules')
var board_view = use('examples/chess/board_view')
var game_state = use('examples/chess/game_state')
var grid = Grid(8, 8)
grid.width = 8
grid.height = 8
board_view.init(grid)
var S = board_view.S, GW = board_view.GW, GH = board_view.GH
var game_cam = camera.make({width: GW, height: GH, pos: {x: GW / 2, y: GH / 2}})
var hud_cam = camera.make({width: GW, height: GH, pos: {x: GW / 2, y: GH / 2}})
input.configure({
action_map: {
select: ['mouse_button_left'],
cancel: ['escape', 'mouse_button_right']
}
})
// Network state
var my_color = null
var server_actor = null
var current_turn = "white"
// Selection state (declared early for $receiver access)
var selectPos = null
var validMoves = []
var hover_gx = -1, hover_gy = -1
board_view.set_status("Connecting to host...")
$contact(function(server) {
if (server) {
server_actor = server
log.console("Connected to host!")
board_view.set_status("Connected, waiting for game...")
} else {
log.error("Failed to connect to host")
board_view.set_status("Connection failed!")
}
}, {address: "127.0.0.1", port: 7777})
$receiver(function(msg) {
if (msg.type == "assign") {
my_color = msg.color
log.console("Assigned color: " + my_color)
board_view.set_status("Playing as " + my_color)
} else if (msg.type == "state") {
current_turn = game_state.deserialize(msg, grid, board_view)
board_view.set_status(current_turn + "'s turn")
selectPos = null
validMoves = []
} else if (msg.type == "result") {
if (!msg.ok) {
board_view.set_status("Move rejected: " + msg.error)
}
}
})
// Local input — client plays black
function compute_valid_moves(from) {
validMoves = []
var piece = grid.at(from)[0]
if (!piece) return
var x = 0, y = 0, to = null, dest = null
for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) {
to = [x, y]
dest = grid.at(to)
if (length(dest) && dest[0].colour == piece.colour) continue
if (rules.canMove(piece, from, to, grid))
push(validMoves, to)
}
}
}
var game_input = {
on_input: function(action, data) {
var clicked = null, cell = null, is_valid = false, i = 0
if (!data.pressed) return
if (!my_color || current_turn != my_color) return
if (action == 'cancel') {
selectPos = null
validMoves = []
board_view.highlight(selectPos, validMoves, hover_gx, hover_gy)
return
}
if (action == 'select' && hover_gx >= 0 && hover_gx < 8 && hover_gy >= 0 && hover_gy < 8) {
clicked = [hover_gx, hover_gy]
cell = grid.at(clicked)
if (selectPos) {
is_valid = false
for (i = 0; i < length(validMoves); i++) {
if (validMoves[i][0] == clicked[0] && validMoves[i][1] == clicked[1]) {
is_valid = true
break
}
}
if (is_valid) {
// Send move to server — don't apply locally
if (server_actor) {
send(server_actor, {type: "move", fx: selectPos[0], fy: selectPos[1], tx: clicked[0], ty: clicked[1]})
}
selectPos = null
validMoves = []
} else if (length(cell) && cell[0].colour == my_color) {
selectPos = clicked
compute_valid_moves(selectPos)
} else {
selectPos = null
validMoves = []
}
} else {
if (length(cell) && cell[0].colour == my_color) {
selectPos = clicked
compute_valid_moves(selectPos)
}
}
board_view.highlight(selectPos, validMoves, hover_gx, hover_gy)
}
}
}
input.player1().possess(game_input)
var comp_config = {
clear: {r: 0.15, g: 0.15, b: 0.2, a: 1},
planes: [
{name: 'game', camera: game_cam, resolution: {width: GW, height: GH}, presentation: 'letterbox'},
{name: 'hud', camera: hud_cam, resolution: {width: GW, height: GH}, presentation: 'stretch'}
]
}
core.start({
width: 640, height: 640, title: "Chess - Client (Black)",
input: function(ev) {
var wp = null
if (ev.type == 'mouse_motion') {
wp = game_cam.window_to_world(ev.pos[0], ev.pos[1])
if (wp) {
hover_gx = floor(wp.x / S)
hover_gy = floor(wp.y / S)
}
}
},
update: function(dt) {
board_view.highlight(selectPos, validMoves, hover_gx, hover_gy)
},
render: function() {
return compositor.execute(compositor.compile(comp_config))
}
})