diff --git a/xtrn/chess/chess.js b/xtrn/chess/chess.js index 4ffa156244cad5c21c6b377fed97dfc58ca29879..b04cfe3053098c42b21a6a08803aa72c37a88656 100644 --- a/xtrn/chess/chess.js +++ b/xtrn/chess/chess.js @@ -28,16 +28,15 @@ function ChessLobby() { this.table_graphic=new Graphic(8,4); this.table_graphic.load(chessroot+"chessbrd.bin"); - this.lobby_graphic=new Graphic(40,24); + this.lobby_graphic=new Graphic(80,24); this.lobby_graphic.load(chessroot+"lobby.bin"); this.clearinput=true; this.table_markers=[]; - this.scrollBar=new Scrollbar(1,1,1,24,"\1y"); - this.list_index=0; + this.scrollBar=new Scrollbar(3,24,35,"horizontal","\1y"); + this.scroll_index=0; this.tables; this.table_index; -/** GAME INITIALIZATION FUNCTIONS **/ this.SplashStart=function() { console.ctrlkey_passthru="+ACGKLOPQRTUVWXYZ_"; @@ -69,19 +68,19 @@ function ChessLobby() } this.Init=function() { - var rows=21; - var columns=37; - var posx=42; - var posy=2; - var input_line={x:42,y:23,columns:37}; - chesschat.Init("Chess Lobby",input_line,columns,rows,posx,posy,true); + var rows=19; + var columns=40; + var posx=40; + var posy=3; + var input_line={x:40,y:23,columns:40}; + chesschat.Init("Chess Lobby",input_line,columns,rows,posx,posy,false,"\1y"); this.Redraw(); } this.ProcessGraphic=function() { - for(posy=0;posy<24;posy++) + for(posx=0;posx<this.lobby_graphic.data.length;posx++) { - for(posx=0;posx<this.lobby_graphic.data.length;posx++) + for(posy=0;posy<this.lobby_graphic.data[posx].length;posy++) { var position={"x" : posx+1, "y" : posy+1}; if(this.lobby_graphic.data[posx][posy].ch=="@") @@ -98,6 +97,7 @@ function ChessLobby() } this.LoadTables=function() { + Log("Loading Games"); var game_files=directory(chessroot+"*.chs"); this.tables=[]; this.table_index=[]; @@ -110,14 +110,16 @@ function ChessLobby() } this.DrawTables=function() { - if(this.tables.length>4) this.scrollBar.draw(this.list_index,this.tables.length); - var index=this.list_index; + var range=(this.tables.length%2==1?this.tables.length+1:this.tables.length); + if(this.tables.length>4) this.scrollBar.draw(this.scroll_index,range); + var index=this.scroll_index; for(i in this.table_markers) { + var posx=this.table_markers[i].x; + var posy=this.table_markers[i].y; + ClearBlock(posx,posy,18,10); if(this.tables[index]) { - posx=this.table_markers[i].x; - posy=this.table_markers[i].y; var tab=this.tables[index]; console.gotoxy(posx+9,posy); @@ -130,9 +132,9 @@ function ChessLobby() this.FormatStats(tab.players["white"].player,posx,posy+5,"white"); this.FormatStats(tab.players["black"].player,posx,posy+7,"black"); this.table_graphic.draw(posx,posy); + write(console.ansi(ANSI_NORMAL)); index++; } - else break; } } this.FormatStats=function(player,x,y,color) @@ -157,9 +159,17 @@ function ChessLobby() this.lobby_graphic.draw(); this.DrawTables(); } + this.Redraw=function() + { + write(console.ansi(ANSI_NORMAL)); + console.clear(); + this.LoadTables(); + this.DrawLobby(); + chesschat.Redraw(); + } -/** MAIN FUNCTIONS **/ +/* MAIN FUNCTIONS */ this.Main=function() { while(1) @@ -168,6 +178,7 @@ function ChessLobby() var k=console.inkey(K_NOCRLF|K_NOSPIN|K_NOECHO,5); if(k) { + var range=(this.tables.length%2==1?this.tables.length+1:this.tables.length); if(this.clearinput) { chesschat.ClearInputLine(); @@ -175,30 +186,51 @@ function ChessLobby() } switch(k.toUpperCase()) { - case KEY_UP: - if(this.list_index>0) this.list_index-=2; + case KEY_LEFT: + if(this.scroll_index>0 && this.tables.length>4) this.scroll_index-=2; break; - case KEY_DOWN: - if(this.list_index<this.tables.length) this.list_index+=2; + case KEY_RIGHT: + if((this.scroll_index+1)<=range && this.tables.length>4) this.scroll_index+=2; break; case "/": - this.LobbyMenu(); + if(!chesschat.buffer.length) this.LobbyMenu(); break; case "\x1b": this.SplashExit(); break; case "?": - this.Help(); + if(!chesschat.buffer.length) this.Help(); break; - default: - if(Chat(chesschat,k)) break; - else this.SplashExit(); } + Chat(k,chesschat); this.LoadTables(); - this.DrawLobby(); + this.DrawTables(); } } } + this.LobbyMenu=function() + { + chesschat.Alert("\1c\1hS\1nelect Game Re\1c\1hd\1nraw \1c\1hN\1new Game \1c\1hR\1nankings"); + var k=console.getkey(K_NOCRLF|K_NOSPIN|K_NOECHO); + switch(k.toUpperCase()) + { + case "N": + this.StartNewGame(); + break; + case "R": + this.ShowRankings(); + break; + case "D": + this.Redraw(); + break; + case "S": + if(this.SelectGame()) this.Init(); + break; + default: + break; + } + chesschat.ClearInputLine(); + } this.Help=function() { //TODO: write help file @@ -218,14 +250,6 @@ function ChessLobby() } else return false; } - this.Redraw=function() - { - write(console.ansi(ANSI_NORMAL)); - console.clear(); - this.LoadTables(); - this.DrawLobby(); - chesschat.Redraw(); - } this.StartNewGame=function() { var newgame=new ChessGame(); @@ -278,29 +302,6 @@ function ChessLobby() chesschat.Alert("\1g\1hGame #" + parseInt(newgame.gamenumber,10) + " created"); newgame.StoreGame(); } - this.LobbyMenu=function() - { - chesschat.Alert("\1c\1hS\1nelect Game Re\1c\1hd\1nraw \1c\1hN\1new Game \1c\1hR\1nankings"); - var k=console.getkey(K_NOCRLF|K_NOSPIN|K_NOECHO); - switch(k.toUpperCase()) - { - case "N": - this.StartNewGame(); - break; - case "R": - this.ShowRankings(); - break; - case "D": - this.Redraw(); - break; - case "S": - if(this.SelectGame()) this.Init(); - break; - default: - break; - } - chesschat.ClearInputLine(); - } this.SplashStart(); this.Main(); diff --git a/xtrn/chess/chessbrd.js b/xtrn/chess/chessbrd.js index 7a41d8b38fc13e3d795fb7b71c7aa50f2bbf1f12..07cc6ccc2fd30a5568500be69170862e6e7c3595 100644 --- a/xtrn/chess/chessbrd.js +++ b/xtrn/chess/chessbrd.js @@ -5,6 +5,14 @@ function GameSession(game) this.board; this.queue; +/* + CHAT ENGINE DEPENDENT FUNCTIONS + + some of these functions are redundant + so as to make modification of the + method of data transfer between nodes/systems + simpler +*/ this.Init=function() { //LOAD GAME DATA @@ -28,38 +36,32 @@ function GameSession(game) this.Cycle(); /* if(this.InCheck(this.king)) { - chesschat.Alert("\1r\1hYou are in check!"); + this.Alert("\1r\1hYou are in check!"); chesschat.ClearLine(); } var checkers=this.InCheck(this.king); if(checkers) { if(this.FindCheckMate(checkers)) { - chesschat.Alert("\1r\1hCheckmate! You lose!"); + this.Alert("\1r\1hCheckmate! You lose!"); return true; } } */ var k=console.inkey(K_NOCRLF|K_NOSPIN|K_NOECHO,5); if(k) - switch(k) { - case KEY_UP: - case KEY_DOWN: - case KEY_LEFT: - case KEY_RIGHT: - this.Move(); - break; - case "/": - this.ChessMenu(); - break; - case "\x1b": - return; - case "?": - this.Help(); - break; - default: - Chat(chesschat,k); - break; + switch(k) + { + case "/": + if(!chesschat.buffer.length) this.ChessMenu(); + break; + case "\x1b": + return; + case "?": + if(!chesschat.buffer.length) this.Help(); + break; + } + Chat(k,chesschat); } } } @@ -69,21 +71,23 @@ function GameSession(game) var y=chesschat.input_line.y; var cmenu=new Menu( "" ,x,y,"\1n","\1c\1h"); - var cmenu_items=[ "~Sit " , - "~Resign " , - "Re~match " , - "~Game Info " , - "Move ~List " , + var cmenu_items=[ "~Sit" , + "~Resign" , + "~New Game" , + "~Game Info" , + "~Move" , + "Move ~List" , "Re~draw" ]; cmenu.add(cmenu_items); if(this.game.started || this.game.currentplayer) cmenu.disable(["S"]); if(!this.game.started || !this.game.currentplayer) cmenu.disable(["R"]); - if(!this.game.finished || !this.game.currentplayer) cmenu.disable(["M"]); + if(!this.game.finished || !this.game.currentplayer) cmenu.disable(["N"]); + if(!this.game.started || this.game.turn!=this.game.currentplayer || this.game.finished) cmenu.disable(["M"]); if(!this.game.movelist.length) cmenu.disable(["L"]); cmenu.displayHorizontal(); var k=console.getkey(K_NOCRLF|K_NOSPIN|K_NOECHO|K_UPPER); - chesschat.ClearInputLine(); + this.ClearAlert(); if(cmenu.items[k] && cmenu.items[k].enabled) switch(k) { @@ -102,10 +106,14 @@ function GameSession(game) case "G": this.GameInfo(); break; + case "M": + this.board.ClearLastMove(); + this.Move(); + break; case "L": this.ListMoves(); break; - case "M": + case "N": this.Rematch(); break; default: @@ -114,8 +122,14 @@ function GameSession(game) else Log("Invalid or Disabled key pressed: " + k); delete cmenu; } - -/** GAMEPLAY FUNCTIONS */ + this.ClearAlert=function() + { + chesschat.ClearInputLine(); + } + this.Alert=function(msg) + { + chesschat.Alert(msg); + } this.Cycle=function() { chesschat.Cycle(); @@ -129,6 +143,20 @@ function GameSession(game) this.game.NextTurn(); } } + this.Redraw=function() + { + console.clear(); + this.board.DrawBoard(); + write(console.ansi(ANSI_NORMAL)); + chesschat.Redraw(); + } + this.Send=function(data,name) + { + this.queue.SendData(data,name); + } + + +/* GAMEPLAY FUNCTIONS */ this.Rematch=function() { } @@ -185,38 +213,71 @@ function GameSession(game) return newrating; } - this.Redraw=function() - { - console.clear(); - this.board.DrawBoard(); - chesschat.Redraw(); - } this.Move=function() { - if(!this.game.started || !this.game.currentplayer || this.game.turn!=this.game.currentplayer) return false; - var from=this.SelectTile(); - if(!from || !this.board.grid[from.x][from.y].contents) return false; - var to=this.SelectTile(from); + var from; + var to; + var placeholder; + var unselect; - if(!to) return false; - else { - var temp_from=this.board.grid[from.x][from.y].contents; - var temp_to=this.board.grid[to.x][to.y].contents; - if(!this.CheckRules(from,to)) return false; - if(this.InCheck(this.game.players[this.game.currentplayer].king)) + while(1) + { + unselect=false; + while(1) { - chesschat.Alert("\1r\1hIllegal Move"); - this.board.grid[from.x][from.y].contents=temp_from; - this.board.grid[to.x][to.y].contents=temp_to; - return false; + from=this.SelectTile(false,from); + if(from==false) return false; + else if( this.board.grid[from.x][from.y].contents && + this.board.grid[from.x][from.y].contents.color == this.game.turn) + break; + else + { + this.Alert("\1r\1hInvalid Selection"); + } } + placeholder=from; + while(1) + { + to=this.SelectTile(from,placeholder); + if(to==false) return false; + else if(from.x==to.x && from.y==to.y) + { + unselect=true; + break; + } + else if(!this.board.grid[to.x][to.y].contents || + this.board.grid[to.x][to.y].contents.color != this.game.turn) + { + if(!this.CheckMove(from,to)) + { + placeholder=to; + this.Alert("\1r\1hIllegal Move"); + } + else break; + } + else + { + placeholder=to; + this.Alert("\1r\1hInvalid Selection"); + } + } + if(!unselect) break; + } + var temp_from=this.board.grid[from.x][from.y].contents; + var temp_to=this.board.grid[to.x][to.y].contents; + + if(this.InCheck(this.game.players[this.game.currentplayer].king)) + { + this.board.grid[from.x][from.y].contents=temp_from; + this.board.grid[to.x][to.y].contents=temp_to; + return false; } this.board.DrawMove(from,to); var move=new ChessMove(from,to); this.game.movelist.push(move); this.game.NextTurn(); this.game.StoreGame(); - this.queue.SendData(move,"move"); + this.Send(move,"move"); return true; } this.GetCastle=function(from,to) @@ -243,19 +304,27 @@ function GameSession(game) this.board.grid[from.x][from.y].contents=false; this.board.DrawMove(from,to); if(this.InCheck(this.game.players[this.game.currentplayer].king)) { - chesschat.Alert("\1r\1hYou are in check!"); + this.Alert("\1r\1hYou are in check!"); } } - this.SelectTile=function(start) + this.SelectTile=function(start,placeholder) { - if(this.board.side=="white") + if(placeholder) selected={"x":placeholder.x, "y":placeholder.y}; + else if(start) selected={"x":start.x, "y":start.y}; + else { - selected=(start?{"x":start.x, "y":start.y}:{"x":0,"y":7}); - while(1) + if(this.board.side=="white") selected={"x":0,"y":7}; + else selected={"x":7,"y":0}; + } + while(1) + { + if(start) this.board.DrawTile(start.x,start.y,true); + this.board.DrawTile(selected.x,selected.y,true); + var key=console.getkey((K_NOECHO,K_NOCRLF,K_UPPER)); + this.ClearAlert(); + if(key=="\r") return selected; + if(this.board.side=="white") { - if(start) this.board.DrawTile(start.x,start.y,true); - var key=console.getkey((K_NOECHO,K_NOCRLF,K_UPPER)); - if(key=="\r") return selected; switch(key) { case KEY_DOWN: @@ -319,15 +388,8 @@ function GameSession(game) } this.board.DrawTile(selected.x,selected.y,true); } - } - else - { - selected=(start?{"x":start.x, "y":start.y}:{"x":7,"y":0}); - while(1) + else { - if(start) this.board.DrawTile(start.x,start.y,true); - var key=console.getkey((K_NOECHO,K_NOCRLF,K_UPPER)); - if(key=="\r") return selected; switch(key) { case KEY_UP: @@ -392,15 +454,12 @@ function GameSession(game) this.board.DrawTile(selected.x,selected.y,true); } } - this.board.DrawTile(selected.x,selected.y,true); } - this.CheckRules=function(from,to) - { - var frompiece=this.board.grid[from.x][from.y].contents; - Log(frompiece.color + " " + frompiece.name + " moving from " + from.x + "," + from.y + " to " + to.x + "," + to.y); + this.CheckMove=function(from,to) + { + var from_tile=this.board.grid[from.x][from.y]; var to_tile=this.board.grid[to.x][to.y]; - if(to.x==from.x && to.y==from.y) { Log("Invalid Move: Target Position same as Source Position") @@ -414,10 +473,23 @@ function GameSession(game) //KING RULESET if(from_tile.contents.name=="king") { - if(this.InCheck(to)) return false; - else if(Math.abs(from.x-to.x)==2 && !this.InCheck(from)) + if(this.InCheck(to)) + { + Log("Invalid Move: Would cause check"); + return false; + } + else if(Math.abs(from.x-to.x)==2) { - if(from_tile.contents.has_moved) return false; + if(this.InCheck(from)) + { + Log("Invalid Move: King is in check"); + return false; + } + if(from_tile.contents.has_moved) + { + Log("Invalid Move: King has already moved and cannot castle"); + return false; + } if(from.x > to.x) { var x=from.x-1; while(x>0) { @@ -439,31 +511,16 @@ function GameSession(game) this.Castle(from,to); } else { - if(Math.abs(from.x-to.x)>1) return false; - if(Math.abs(from.y-to.y)>1) return false; + if(Math.abs(from.x-to.x)>1 || Math.abs(to.x-to.y)>1) + { + Log("Invalid Move: King can only move one space unless castling"); + return false; + } } this.game.players[this.game.currentplayer].king=to; } - else { - if(!this.CheckMove(from,to)) return false; - this.board.grid[to.x][to.y].contents=this.board.grid[from.x][from.y].contents; - this.board.grid[to.x][to.y].contents.has_moved=true; - this.board.grid[from.x][from.y].contents=false; - } - this.board.DrawTile(from.x,from.y); - this.board.DrawTile(to.x,to.y); - return true; - } - this.CheckMove=function(from,to) - { - var from_tile=this.board.grid[from.x][from.y]; - var to_tile=this.board.grid[to.x][to.y]; - - //NECESSARY FOR DETERMINING CHECK... SINCE KING IS NOT DEFINED IN THIS RULESET - if(to.x==from.x && to.y==from.y) return false; - //PAWN RULESET - if(from_tile.contents.name=="pawn") + else if(from_tile.contents.name=="pawn") { var xgap=Math.abs(from.x-to.x); var ygap=Math.abs(from.y-to.y); @@ -605,6 +662,11 @@ function GameSession(game) } else return false; } + + Log(from_tile.contents.color + " " + from_tile.contents.name + " moved from " + from.x + "," + from.y + " to " + to.x + "," + to.y); + to_tile.contents=from_tile.contents; + to_tile.contents.has_moved=true; + from_tile.contents=false; return true; } this.Castle=function(from,to) @@ -864,7 +926,6 @@ function ChessGame(gamefile) this.rated=gFile.iniGetValue(null,"rated"); this.timed=gFile.iniGetValue(null,"timed"); - Log("Loaded game: " + this.gamenumber); gFile.close(); } this.LoadGameData=function()