Difference between revisions of "Chess game"
m |
m |
||
Line 1: | Line 1: | ||
[[:Image:Chess selection.jpg|Screenshot of the gameplay]] | [[:Image:Chess selection.jpg|Screenshot of the gameplay]] | ||
− | = Source = | + | == Source == |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
; | ; | ||
Line 646: | Line 646: | ||
== Help == | == Help == | ||
− | a | + | |
+ | === THE GAME === | ||
+ | |||
+ | Singleplayer mode is only for debugging and testing, not actually to play. | ||
+ | This game is meant to be played as multiplayer, where other player starts a server (whites), | ||
+ | and other connects to this server (blacks) | ||
+ | |||
+ | === SERVER and CONNECTING === | ||
+ | |||
+ | Two connection types are available, sockets and through IRC with /notice or /msg | ||
+ | Connection type must be same on both players, the one starting a server must start a server using sockets | ||
+ | (default), or from server dialog select IRC and input the other players nick (in active server connection) | ||
+ | |||
+ | The connecting player must then select the same connection method from the connect dialog, and input | ||
+ | the servers IP (sockets) or NICK (IRC), | ||
+ | note that the same PORT must be used on both clients. | ||
+ | |||
+ | === IMPLEMENTED RULES === (read more about the rules from wikipedia) | ||
+ | |||
+ | All the pieces move correctly, and you cannot make a move that wouldn't go by the rules. | ||
+ | Pawn can perform en passant move, and if advanced to the 8th rank (other side of the board), it gets promoted to queen,rook,bishop,knight of the same color. | ||
+ | King and rook can perform castling move, if all the requirements are met, selecting king will highlight the rook, if then clicked on the rook, the castling is performed. | ||
+ | IF king is in check, the game will show the selectiong borders in squares you cannot move, but won't let you move there if you try. | ||
+ | |||
+ | === Mouse & menus === | ||
+ | |||
+ | You select pieces by clicking them, and move them by clicking on the target square, clicking the selected piece will de-select it. | ||
+ | You'll find last move from bottom right hand side of the board, clicking it will append the log-window on the right side, where you will see | ||
+ | 40 (with 100px squares) or 24 (60px squares) last moves, doubleclicking a move in the log-window will highlight the move on the board. | ||
+ | Right clicking anywhere brings you a popup-menu, where you will always find options and help, if in game, also save & load are in this menu. | ||
+ | If in multiplayer mode, there's also "send msg", from where you can send a message to other players infobar (bottom left hand side on the board). | ||
+ | Right clicking on the log menu let's you save the log. | ||
+ | |||
+ | === Saving & loading === | ||
+ | |||
+ | You can save and load your gamestate, the game will create 2 files into your /chess-folder | ||
+ | YYYY-MM-DD-HHNNSS_board_OPPONENTSNAME.save and YYYY-MM-DD-HHNNSS_info_OPPONENTSNAME.save | ||
+ | There will be notification for you, if the opponent loads a game, telling you what game he/she loaded. | ||
+ | |||
+ | === Options === | ||
+ | |||
+ | Logging format: let's you choose the logging format between "International (Pe2xf1Q+)" and "New (P E2->F1 Q take+check)" | ||
+ | Square size: Width & height of the squares in the board in pixels. | ||
+ | IRC send method: Uses /msg OPPONENT or /notice OPPONENT to send information if connected via IRC. | ||
+ | Selection frames: Switch on/off showing of the borders in squares where you can move. | ||
+ | |||
[[Category:Script_Archive]] | [[Category:Script_Archive]] |
Revision as of 19:48, 7 April 2007
Contents
Source
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Chess game with picture windows by Cail at Quakenet -> #help.script ; ; Includes singleplayer and multiplayer. ; In singleplayer mode you move black's and white's in turns. ; Multiplayer was the main idea, and the game uses sockets to start a server and to connect to a server ; Get the pieces at: http://lost.kapsi.fi/cail/chess.zip (images originally from mediawiki, by Wapcaplet) ; After you've put the images of pieces into /mircdir/chess directory, start the game by typing /chess and choose your mode ; Also support saving and loading the game state, for singleplayer and multiplayer. ; ; TODO: ; - function to check if a square is attacked ; - castling-move for king and rook ; - comments for the code ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias chess { if ($hget(chess.board)) { hfree chess.board } | hmake chess.board 64 if ($hget(chess.info)) { hfree chess.info } | hmake chess.info 64 window -dfpw0C +nft @chess 0 0 840 860 drawrect -rf @chess 3684408 0 0 0 840 860 drawrect -r @chess 65280 1 60 350 300 50 drawrect -r @chess 65280 1 60 410 300 50 drawrect -r @chess 65280 1 60 470 300 50 drawtext -ro @chess 16749691 verdana 22 70 360 single player drawtext -ro @chess 16749691 verdana 22 70 420 connect to a server drawtext -ro @chess 16749691 verdana 22 70 480 start a server } menu @chess { sclick: chess_click save:chess_save $iif($hget(chess.info,init),load):chess_load $dialog(load_table,load_table) } dialog load_table { title "Chess" size -1 -1 422 220 option pixels text "Select a saved game.", 1, 7 5 417 20,result list 2, 5 25 410 200, sort button "", 3, -20 -20 1 1, ok } on 1:dialog:load_table:init:*:{ noop $findfile(chess,*board*.save,0,parse_save $1-) } alias -l parse_save { noop $regex($1-,/\\([^\\]+)_board_(.+)\.save/g) did -a $dname 2 $regml(1) - $regml(2) } on 1:dialog:load_table:dclick:2:{ did -ra $dname 1 $did($dname,2).seltext dialog -k $dname } alias -l chess_load { hdel -w chess.board * hdel -w chess.info * hload chess.board $+(chess\,$1,_board_,$3,.save) hload chess.info $+(chess\,$1,_info_,$3,.save) var %y = 1 while (%y <= 8) { var %x = 1 while (%x <= 8) { var %dx = $get_square(%x) var %dy = $get_square(%y) drawrect -rf @chess $get_color(%x,%y) 0 %dx %dy 100 100 if ($hget(chess.board,$+(%y,%x))) { draw_piece %dx %dy $v1 $get_color(%x,%y) } inc %x } inc %y } if ($hget(chess.info,mode) == mp) { chess_send load $1 $3 if ($hget(chess.info,own_turn)) { print_info light_blue Game loaded succesfully, your turn. } else { print_info light_blue Game loaded succesfully, $hget(chess.info,opponent) $+ 's turn. } } } alias -l chess_save { hsave chess.board $+(chess/,$asctime(yyyy-mm-dd),_board_,$iif($hget(chess.info,mode) == sp,sp,$hget(chess.info,opponent)),.save) hsave chess.info $+(chess/,$asctime(yyyy-mm-dd),_info_,$iif($hget(chess.info,mode) == sp,sp,$hget(chess.info,opponent)),.save) } alias -l chess_initiate { hadd chess.info clr_select red var %y = 1 while (%y <= 8) { var %x = 1 while (%x <= 8) { var %dx = $get_square(%x) var %dy = $get_square(%y) drawrect -rf @chess $get_color(%x,%y) 0 %dx %dy 100 100 if ($get_piece(%y,%x)) { hadd chess.board $+(%y,%x) $v1 | draw_piece %dx %dy $v1 $get_color(%x,%y) } inc %x } inc %y } } alias -l chess_click { if (!$inrect($mouse.x,$mouse.y,20,20,800,800)) { return } elseif (!$hget(chess.info,init)) { ; SELECT: single player if ($inrect($mouse.x,$mouse.y,60,350,300,50)) { hadd chess.info init 1 | hadd chess.info clr_own w | hadd chess.info mode sp chess_initiate } ; SELECT: connect to a server elseif ($inrect($mouse.x,$mouse.y,60,410,300,50)) { hadd chess.info init 1 | hadd chess.info clr_own b | hadd chess.info mode mp | hadd chess.info last_moved b connect_dialog } ; SELECT: start a server elseif ($inrect($mouse.x,$mouse.y,60,470,300,50)) { hadd chess.info init 1 | hadd chess.info clr_own w | hadd chess.info mode mp | hadd chess.info own_turn 1 start_server | drawtext -ro @chess 16749691 verdana 22 370 480 waiting for other player... } return } if ($hget(chess.info,mode) == mp) && (!$hget(chess.info,own_turn)) { return } if ($hget(chess.info,mode) == sp) { var %clr_own = $iif($hget(chess.info,last_moved) == w,b,w) | hadd chess.info clr_own %clr_own } else { var %clr_own = $hget(chess.info,clr_own) } var %x = $left($calc($mouse.x -20+100),1) var %y = $left($calc($mouse.y -20+100),1) var %xy = $+(%y,%x) var %clr_selected = $left($hget(chess.board,%xy),1) var %clr_moved = $hget(chess.info,clr_moved) var %last.x = $hget(chess.info,last.x) var %last.y = $hget(chess.info,last.y) var %last.xy = $+(%last.y,%last.x) var %y-1 = $bw(%y,1,%clr_moved) var %xy-1 = $+(%y-1,%x) var %is_last = $iif((%x == %last.x) && (%y == %last.y),$true,$false) var %current_selections = $hget(chess.info,current_selections) var %selected = $hget(chess.info,selected) if (!%selected) && (%clr_selected != %clr_own) && ($hget(chess.board,%xy)) { return } elseif (%selected) && (%clr_selected == %clr_own) { clear_selections %last.xy %current_selections | hdel chess.info selected | hdel chess.info current_selections if (%is_last) { return } } elseif (!$hget(chess.board,%xy) && !$hget(chess.info,selected)) { return } elseif (!$istok(%current_selections,%xy,32)) && (%current_selections) { return } ; a piece is selected, and moveable if ($hget(chess.info,selected)) { hadd chess.info last_moved %clr_own ;if ($hget(chess.board,%xy)) { hadd chess.taken $v1 } if ($hget(chess.info,en_passant) == %xy-1) && ($left($hget(chess.board,%xy-1),1) != %clr_own) { ;hadd chess.taken $+($hget(chess.board,%xy-1),%xy-1) 1 hdel chess.board %xy-1 drawrect -rf @chess $get_color(%x,%y-1) 0 $get_square(%x) $get_square(%y-1) 100 100 } hdel chess.info en_passant drawrect -rf @chess $get_color(%last.x,%last.y) 0 $get_square(%last.x) $get_square(%last.y) 100 100 if ($hget(chess.board,%last.xy)) { draw_piece $get_square(%x) $get_square(%y) $v1 $get_color(%x,%y) } noop $chess_move(%last.xy,->,%xy) clear_selections %current_selections %last.xy hdel chess.info selected hdel chess.info current_selections if ($hget(chess.info,mode) == mp) { if (!$hget(chess.info,just_switched)) { chess_send move %last.xy %xy } print_info light_blue $hget(chess.info,opponent) $+ 's turn hdel chess.info own_turn } hdel chess.info just_switched } ; nothing selected, so we're selecting a piece else { var %piece = $hget(chess.board,%xy) draw_selection %x %y green ;draw_piece $get_square(%x) $get_square(%y) %piece $get_color(%x,%y) hadd chess.info selected 1 chess_piece_options %piece %x %y } hadd chess.info clr_moved %clr_selected hadd chess.info last.x %x hadd chess.info last.y %y } alias -l draw_piece { drawpic -c @chess $1 $2 0 0 100 100 $+(chess/,$3,_,$iif($4,w,b),.png) } alias -l draw_selection { drawrect -r @chess $clr_replace($3) 3 $calc($get_square($1) +1) $calc($get_square($2) +1) 98 98 } alias -l chess_move { var %piece = $hget(chess.board,$1) var %move_len = $abs($calc($left($3,1) - $left($1,1))) if ($right(%piece,-2) == pawn) { if ($istok(1 8,$left($3,1),32)) { noop $dialog(choose_piece,choose_piece) switch_piece %newpiece $3 $1 if ($hget(chess.info,mode) == mp) { chess_send switch %newpiece $3 $1 } hadd chess.info just_switched 1 unset %newpiece return } elseif (%move_len == 2) { hadd chess.info en_passant $3 } } hadd chess.board $3 %piece hdel chess.board $1 return } alias -l switch_piece { var %x = $mid($2,1,1) var %y = $mid($2,2,1) var %dx = $get_square(%x) var %dy = $get_square(%y) var %new_piece = $1 hadd chess.board $2 %new_piece hdel chess.board $3 draw_piece %dy %dx %new_piece $get_color(%x,%y) } alias -l clr_replace { return $replacex($1,red,255,green,65280,blue,16732457,yellow,2751743,light_blue,16749691) } alias -l get_color { return $iif($calc(($1 -($2 % 2)) % 2),0,16777215) } alias -l get_piece { if ($istok(1 2 7 8,$1,32)) { if ($1 == 2) { return w_pawn } elseif ($1 == 7) { return b_pawn } elseif ($1 == 8) { return $gettok(b_rook b_knight b_bishop b_queen b_king b_bishop b_knight b_rook,$2,32) } else { return $gettok(w_rook w_knight w_bishop w_queen w_king w_bishop w_knight w_rook,$2,32) } } } alias -l get_square { return $calc((($1 -1) *100) +20) } alias -l clear_selections { var %z = 1 while ($gettok($1-,%z,32)) { var %x = $mid($v1,2,1) var %y = $mid($v1,1,1) var %ispiece = $hget(chess.board,$v1) if ($v1 != 99) { drawrect -rf @chess $get_color(%x,%y) 0 $get_square(%x) $get_square(%y) 100 100 if (%ispiece) { draw_piece $get_square(%x) $get_square(%y) $v1 $get_color(%x,%y) } } inc %z } } alias -l print_info { drawrect -rf @chess 3684408 0 20 830 840 20 | drawtext -ro @chess $clr_replace($1) verdana 16 20 830 $2- } alias -l check_square { if (!$hget(chess.board,$+($2,$1))) || ($left($hget(chess.board,$+($2,$1)),1) == $iif($hget(chess.info,clr_own) == w,b,w)) { return $true } } alias -l in_board { if ($1 isnum 1-8) && ($2 isnum 1-8) { return $true } } alias -l draw+select { draw_selection $1 $2 $hget(chess.info,clr_select) | return $+($2,$1) } alias -l fw { return $calc($1 $iif($3 == w,+,-) $2) } alias -l bw { return $calc($1 $iif($3 == w,-,+) $2) } alias -l chess_piece_options { var %piece = $right($1,-2) var %clr_own = $left($1,1) var %clr_opponent = $iif(%clr_own == w,b,w) var %x = $2 var %y = $3 ; PAWN if (%piece == pawn) { var %y+1 = $fw(%y,1,%clr_own) var %y+2 = $fw(%y,2,%clr_own) var %x+1 = $calc(%x +1) var %x-1 = $calc(%x -1) var %take_left = $+(%y+1,%x+1) var %take_right = $+(%y+1,%x-1) if (($left($hget(chess.board,%take_left),1) == %clr_opponent) || (($hget(chess.info,en_passant) == $+(%y,%x+1)) && ($left($hget(chess.board,$+(%y,%x+1)),1) == %clr_opponent))) { var %select = %select $draw+select(%x+1,%y+1) } if (($left($hget(chess.board,%take_right),1) == %clr_opponent) || (($hget(chess.info,en_passant) == $+(%y,%x-1)) && ($left($hget(chess.board,$+(%y,%x-1)),1) == %clr_opponent))) { var %select = %select $draw+select(%x-1,%y+1) } if (!$hget(chess.board,$+(%y+1,%x))) && (%y+1 <= 8) && (%y+1 > 1) { var %select = %select $draw+select(%x,%y+1) ; 2 steps for first move if ($istok(2 7,%y,32)) && (!$hget(chess.board,$+(%y+2,%x))) && (%y+2 <= 8) && (%y+2 > 1) { var %select = %select $draw+select(%x,%y+2) } } hadd chess.info current_selections $iif(%select,$v1,99) return } ; ROOK elseif (%piece == rook) { ; :: RIGHT var %z = $iif(%x == 8,9,$calc(%x +1)) while (%z <= 8) { if ($hget(chess.board,$+(%y,%z))) { break } | var %select = %select $draw+select(%z,%y) | inc %z } if ($left($hget(chess.board,$+(%y,%z)),1) == %clr_opponent) { var %select = %select $draw+select(%z,%y) } ; :: LEFT var %z = $iif(%x == 1,0,$calc(%x -1)) while (%z >= 1) { if ($hget(chess.board,$+(%y,%z))) { break } | var %select = %select $draw+select(%z,%y) | dec %z } if ($left($hget(chess.board,$+(%y,%z)),1) == %clr_opponent) { var %select = %select $draw+select(%z,%y) } ; :: UP var %z = $iif(%y == 1,0,$calc(%y -1)) while (%z >= 1) { if ($hget(chess.board,$+(%z,%x))) { break } | var %select = %select $draw+select(%x,%z) | dec %z } if ($left($hget(chess.board,$+(%z,%x)),1) == %clr_opponent) { var %select = %select $draw+select(%x,%z) } ; :: DOWN var %z = $iif(%y == 8,9,$calc(%y +1)) while (%z <= 8) { if ($hget(chess.board,$+(%z,%x))) { break } | var %select = %select $draw+select(%x,%z) | inc %z } if ($left($hget(chess.board,$+(%z,%x)),1) == %clr_opponent) { var %select = %select $draw+select(%x,%z) } hadd chess.info current_selections $iif(%select,$v1,99) return } ; BISHOP elseif (%piece == bishop) { ; :: LEFT-UP var %sx = $iif(%x == 1,0,$calc(%x -1)) var %sy = $iif(%y == 1,0,$calc(%y -1)) while (%sx >= 1) && (%sy >= 1) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | dec %sx | dec %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } ; :: LEFT-DOWN var %sx = $iif(%x == 1,0,$calc(%x -1)) var %sy = $iif(%y == 8,9,$calc(%y +1)) while (%sx >= 1) && (%sy <= 8) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | dec %sx | inc %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } ; :: RIGHT-UP var %sx = $iif(%x == 8,9,$calc(%x +1)) var %sy = $iif(%y == 1,0,$calc(%y -1)) while (%sx <= 8) && (%sy >= 1) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | inc %sx | dec %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } ; :: RIGHT-DOWN var %sx = $iif(%x == 8,9,$calc(%x +1)) var %sy = $iif(%y == 8,9,$calc(%y +1)) while (%sx <= 8) && (%sy <= 8) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | inc %sx | inc %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } hadd chess.info current_selections $iif(%select,$v1,99) return } ; QUEEN elseif (%piece == queen) { ; :: RIGHT var %z = $iif(%x == 8,9,$calc(%x +1)) while (%z <= 8) { if ($hget(chess.board,$+(%y,%z))) { break } | var %select = %select $draw+select(%z,%y) | inc %z } if ($left($hget(chess.board,$+(%y,%z)),1) == %clr_opponent) { var %select = %select $draw+select(%z,%y) } ; :: LEFT var %z = $iif(%x == 1,0,$calc(%x -1)) while (%z >= 1) { if ($hget(chess.board,$+(%y,%z))) { break } | var %select = %select $draw+select(%z,%y) | dec %z } if ($left($hget(chess.board,$+(%y,%z)),1) == %clr_opponent) { var %select = %select $draw+select(%z,%y) } ; :: UP var %z = $iif(%y == 1,0,$calc(%y -1)) while (%z >= 1) { if ($hget(chess.board,$+(%z,%x))) { break } | var %select = %select $draw+select(%x,%z) | dec %z } if ($left($hget(chess.board,$+(%z,%x)),1) == %clr_opponent) { var %select = %select $draw+select(%x,%z) } ; :: DOWN var %z = $iif(%y == 8,9,$calc(%y +1)) while (%z <= 8) { if ($hget(chess.board,$+(%z,%x))) { break } | var %select = %select $draw+select(%x,%z) | inc %z } if ($left($hget(chess.board,$+(%z,%x)),1) == %clr_opponent) { var %select = %select $draw+select(%x,%z) } ; :: LEFT-UP var %sx = $iif(%x == 1,0,$calc(%x -1)) var %sy = $iif(%y == 1,0,$calc(%y -1)) while (%sx >= 1) && (%sy >= 1) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | dec %sx | dec %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } ; :: LEFT-DOWN var %sx = $iif(%x == 1,0,$calc(%x -1)) var %sy = $iif(%y == 8,9,$calc(%y +1)) while (%sx >= 1) && (%sy <= 8) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | dec %sx | inc %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } ; :: RIGHT-UP var %sx = $iif(%x == 8,9,$calc(%x +1)) var %sy = $iif(%y == 1,0,$calc(%y -1)) while (%sx <= 8) && (%sy >= 1) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | inc %sx | dec %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } ; :: RIGHT-DOWN var %sx = $iif(%x == 8,9,$calc(%x +1)) var %sy = $iif(%y == 8,9,$calc(%y +1)) while (%sx <= 8) && (%sy <= 8) { if ($hget(chess.board,$+(%sy,%sx))) { break } | var %select = %select $draw+select(%sx,%sy) | inc %sx | inc %sy } if ($left($hget(chess.board,$+(%sy,%sx)),1) == %clr_opponent) { var %select = %select $draw+select(%sx,%sy) } hadd chess.info current_selections $iif(%select,$v1,99) return } ; KING elseif (%piece == king) { var %x-1 = $iif(%x == 1,0,$calc(%x -1)) var %y-1 = $iif(%y == 1,0,$calc(%y -1)) var %x+1 = $iif(%x == 8,9,$calc(%x +1)) var %y+1 = $iif(%y == 8,9,$calc(%y +1)) ; :: RIGHT if ($check_square(%x+1,%y)) && ($in_board(%x+1,%y)) { var %select = %select $draw+select(%x+1,%y) } ; :: LEFT if ($check_square(%x-1,%y)) && ($in_board(%x-1,%y)) { var %select = %select $draw+select(%x-1,%y) } ; :: UP if ($check_square(%x,%y-1)) && ($in_board(%x,%y-1)) { var %select = %select $draw+select(%x,%y-1) } ; :: DOWN if ($check_square(%x,%y+1)) && ($in_board(%x,%y+1)) { var %select = %select $draw+select(%x,%y+1) } ; :: LEFT-UP if ($check_square(%x-1,%y-1)) && ($in_board(%x-1,%y-1)) { var %select = %select $draw+select(%x-1,%y-1) } ; :: LEFT-DOWN if ($check_square(%x-1,%y+1)) && ($in_board(%x-1,%y+1)) { var %select = %select $draw+select(%x-1,%y+1) } ; :: RIGHT-UP if ($check_square(%x+1,%y-1)) && ($in_board(%x+1,%y-1)) { var %select = %select $draw+select(%x+1,%y-1) } ; :: RIGHT-DOWN if ($check_square(%x+1,%y+1)) && ($in_board(%x+1,%y+1)) { var %select = %select $draw+select(%x+1,%y+1) } hadd chess.info current_selections $iif(%select,$v1,99) return } ; KNIGHT elseif (%piece = knight) { var %x+1 = $iif(%x == 8,9,$calc(%x +1)) var %x-1 = $iif(%x == 1,0,$calc(%x -1)) var %x+2 = $iif(%x == 8,9,$calc(%x +2)) var %x-2 = $iif(%x == 1,0,$calc(%x -2)) var %y+1 = $iif(%y == 8,9,$calc(%y +1)) var %y-1 = $iif(%y == 1,0,$calc(%y -1)) var %y+2 = $iif(%y == 8,9,$calc(%y +2)) var %y-2 = $iif(%y == 1,0,$calc(%y -2)) ; :: DOWN-2 RIGHT-1 if ($check_square(%x+1,%y+2)) && ($in_board(%x+1,%y+2)) { var %select = %select $draw+select(%x+1,%y+2) } ; :: DOWN-2 LEFT-1 if ($check_square(%x-1,%y+2)) && ($in_board(%x-1,%y+2)) { var %select = %select $draw+select(%x-1,%y+2) } ; :: DOWN-1 RIGHT-2 if ($check_square(%x+2,%y+1)) && ($in_board(%x+2,%y+1)) { var %select = %select $draw+select(%x+2,%y+1) } ; :: DOWN-1 LEFT-2 if ($check_square(%x-2,%y+1)) && ($in_board(%x-2,%y+1)) { var %select = %select $draw+select(%x-2,%y+1) } ; :: UP-2 RIGHT-1 if ($check_square(%x+1,%y-2)) && ($in_board(%x+1,%y-2)) { var %select = %select $draw+select(%x+1,%y-2) } ; :: UP-2 LEFT-1 if ($check_square(%x-1,%y-2)) && ($in_board(%x-1,%y-2)) { var %select = %select $draw+select(%x-1,%y-2) } ; :: UP-1 RIGHT-2 if ($check_square(%x+2,%y-1)) && ($in_board(%x+2,%y-1)) { var %select = %select $draw+select(%x+2,%y-1) } ; :: UP-1 LEFT-2 if ($check_square(%x-2,%y-1)) && ($in_board(%x-2,%y-1)) { var %select = %select $draw+select(%x-2,%y-1) } hadd chess.info current_selections $iif(%select,$v1,99) return } } dialog choose_piece { title "Chess" size -1 -1 422 130 option pixels text "Select a new piece.",5, 7 5 417 20 icon 1, 5 25 100 100 icon 2, 108 25 100 100 icon 3, 211 25 100 100 icon 4, 314 25 100 100 } on 1:dialog:choose_piece:init:*:{ did -g $dname 1 $+(chess/,$hget(chess.info,clr_own),_queen_w.png) did -g $dname 2 $+(chess/,$hget(chess.info,clr_own),_rook_w.png) did -g $dname 3 $+(chess/,$hget(chess.info,clr_own),_bishop_w.png) did -g $dname 4 $+(chess/,$hget(chess.info,clr_own),_knight_w.png) } on 1:dialog:choose_piece:sclick:1,2,3,4:{ set %newpiece $+($hget(chess.info,clr_own),_,$gettok(queen rook bishop knight,$did,32)) dialog -x choose_piece } on *:close:@chess:{ hfree chess.board hfree chess.info ;hfree chess.taken if ($sock(chess_connect)) { sockclose chess_connect } if ($sock(chess)) { sockclose chess } } ;; socket part alias -l connect_dialog { noop $dialog(chess_connect,chess_connect) } dialog chess_connect { title "Create chess connection" size -1 -1 275 50 option pixels text "IP", 1, 7 5 100 20 text "PORT", 2, 111 5 100 20 edit "", 3, 5 22 100 20 edit "", 4, 108 22 100 20 button "connect", 5, 211 21 60 22,default } on 1:dialog:chess_connect:init:*:{ did -a $dname 3 %chess.ip did -a $dname 4 $iif(%chess.port,$v1,6666) } on 1:dialog:chess_connect:sclick:5:{ set %chess.ip $did($dname,3) set %chess.port $did($dname,4) dialog -x chess_connect connect_to_server } alias start_server { sockclose chess_connect socklisten chess_connect 6666 } alias -l connect_to_server { sockopen chess %chess.ip %chess.port } alias -l chess_send { sockwrite -n chess $1- } on *:socklisten:chess_connect:{ chess_initiate print_info light_blue You start. sockaccept chess chess_send init $me } on *:sockopen:chess:{ chess_initiate | chess_send init $me } on *:sockread:chess:{ var %t sockread %t if ($gettok(%t,1,32) == init) { hadd chess.info opponent $gettok(%t,2,32) if (!$hget(chess.info,own_turn)) { print_info light_blue $gettok(%t,2,32) starts. } } elseif ($gettok(%t,1,32) == move) { hadd chess.info own_turn 1 var %last.xy = $gettok(%t,2,32) var %last.x = $mid(%last.xy,2,1) var %last.y = $mid(%last.xy,1,1) var %xy = $gettok(%t,3,32) var %x = $mid(%xy,2,1) var %y = $mid(%xy,1,1) drawrect -rf @chess $get_color(%last.x,%last.y) 0 $get_square(%last.x) $get_square(%last.y) 100 100 if ($hget(chess.board,%last.xy)) { draw_piece $get_square(%x) $get_square(%y) $v1 $get_color(%x,%y) } noop $chess_move(%last.xy,->,%xy) draw_selection %last.x %last.y light_blue draw_selection %x %y yellow .timerclrlast $+ %xy 1 5 clear_selections %last.xy %xy print_info light_blue Your turn. } elseif ($gettok(%t,1,32) == load) { print_info light_blue $hget(chess.info,opponent) loaded a game: $gettok(%t,2,32) with $gettok(%t,3,32) } elseif ($gettok(%t,1,32) == switch) { switch_piece $gettok(%t,2,32) $gettok(%t,3,32) $gettok(%t,4,32) clear_selections $gettok(%t,4,32) hadd chess.info own_turn 1 print_info light_blue Your turn. } } on *:sockclose:chess:{ print_info red $hget(chess.info,opponent) disconnected. }
Help
THE GAME
Singleplayer mode is only for debugging and testing, not actually to play. This game is meant to be played as multiplayer, where other player starts a server (whites), and other connects to this server (blacks)
SERVER and CONNECTING
Two connection types are available, sockets and through IRC with /notice or /msg Connection type must be same on both players, the one starting a server must start a server using sockets (default), or from server dialog select IRC and input the other players nick (in active server connection)
The connecting player must then select the same connection method from the connect dialog, and input the servers IP (sockets) or NICK (IRC), note that the same PORT must be used on both clients.
=== IMPLEMENTED RULES === (read more about the rules from wikipedia)
All the pieces move correctly, and you cannot make a move that wouldn't go by the rules. Pawn can perform en passant move, and if advanced to the 8th rank (other side of the board), it gets promoted to queen,rook,bishop,knight of the same color. King and rook can perform castling move, if all the requirements are met, selecting king will highlight the rook, if then clicked on the rook, the castling is performed. IF king is in check, the game will show the selectiong borders in squares you cannot move, but won't let you move there if you try.
You select pieces by clicking them, and move them by clicking on the target square, clicking the selected piece will de-select it. You'll find last move from bottom right hand side of the board, clicking it will append the log-window on the right side, where you will see 40 (with 100px squares) or 24 (60px squares) last moves, doubleclicking a move in the log-window will highlight the move on the board. Right clicking anywhere brings you a popup-menu, where you will always find options and help, if in game, also save & load are in this menu. If in multiplayer mode, there's also "send msg", from where you can send a message to other players infobar (bottom left hand side on the board). Right clicking on the log menu let's you save the log.
Saving & loading
You can save and load your gamestate, the game will create 2 files into your /chess-folder YYYY-MM-DD-HHNNSS_board_OPPONENTSNAME.save and YYYY-MM-DD-HHNNSS_info_OPPONENTSNAME.save There will be notification for you, if the opponent loads a game, telling you what game he/she loaded.
Options
Logging format: let's you choose the logging format between "International (Pe2xf1Q+)" and "New (P E2->F1 Q take+check)" Square size: Width & height of the squares in the board in pixels. IRC send method: Uses /msg OPPONENT or /notice OPPONENT to send information if connected via IRC. Selection frames: Switch on/off showing of the borders in squares where you can move.