From 061375a56afb203c2d99206f4acefaa791369fcd Mon Sep 17 00:00:00 2001 From: AAA Date: Sun, 24 Sep 2017 23:08:51 -0500 Subject: [PATCH 01/25] changed a few things --- client.html | 4 ++-- server.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client.html b/client.html index 598a6a6..3bf8581 100644 --- a/client.html +++ b/client.html @@ -13,12 +13,12 @@ // Set event handlers. ws.onopen = function() { - output("onopen"); + output("Connection established"); }; ws.onmessage = function(e) { // e.data contains received string. - output("onmessage: " + e.data); + output("" + e.data); }; ws.onclose = function() { diff --git a/server.py b/server.py index f0587c6..e9106b5 100644 --- a/server.py +++ b/server.py @@ -16,6 +16,8 @@ def message_received(client, server, message): if len(message) > 200: message = message[:200]+'..' print("Client(%d) said: %s" % (client['id'], message)) + server.send_message_to_all(message) + PORT=9001 From 481f605552074ec8822aa37f4bd314aa6ab2600e Mon Sep 17 00:00:00 2001 From: AAA Date: Sun, 24 Sep 2017 23:10:27 -0500 Subject: [PATCH 02/25] forgot to add Procfile --- Procfile | 1 + 1 file changed, 1 insertion(+) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..098de65 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +python server.py \ No newline at end of file From d4e43ec44966b4ab2269e14b1466a710e743992b Mon Sep 17 00:00:00 2001 From: AAA Date: Sun, 24 Sep 2017 23:24:19 -0500 Subject: [PATCH 03/25] fixed Procfile --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 098de65..d5e2bb1 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -python server.py \ No newline at end of file +web: python server.py \ No newline at end of file From 08c2ccd2a10db17c9334ae31c02d98115d89e65e Mon Sep 17 00:00:00 2001 From: AAA Date: Mon, 25 Sep 2017 17:41:26 -0500 Subject: [PATCH 04/25] Switch to multiplayer Chess game --- board.png | Bin 0 -> 28204 bytes client.html | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 board.png diff --git a/board.png b/board.png new file mode 100644 index 0000000000000000000000000000000000000000..c8b310f86e4dfac53417365d141dee270554f8a2 GIT binary patch literal 28204 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 b>Xg_1h>QIfV!=1O!A_lY_`cl6_vZfqi;{%a literal 0 HcmV?d00001 diff --git a/client.html b/client.html index 3bf8581..0520493 100644 --- a/client.html +++ b/client.html @@ -2,7 +2,22 @@ Simple client - - - -
- - - -
-
- + From a0d919dd9b9821fa8b5bce3076cf20f5fd48a487 Mon Sep 17 00:00:00 2001 From: AAA Date: Tue, 3 Oct 2017 19:56:38 -0500 Subject: [PATCH 05/25] removed image background, added two pieces --- client.html | 188 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 179 insertions(+), 9 deletions(-) diff --git a/client.html b/client.html index 0520493..4e979ab 100644 --- a/client.html +++ b/client.html @@ -11,6 +11,7 @@ +canvas.addEventListener('click', selectPiece);
@@ -66,24 +67,193 @@ replace(/>/, ">").replace(/"/, """); // " log.innerHTML = escaped + "
" + log.innerHTML; } -//Credit for canvas image draw https://stackoverflow.com/questions/14012768/html5-canvas-background-image +var selectedPiece=null; + + //Credit for canvas image draw https://stackoverflow.com/questions/14012768/html5-canvas-background-image var canvas = document.getElementById("myCanvas"), ctx = canvas.getContext("2d"); -canvas.width = 512; -canvas.height = 512; +canvasWidth=512 +canvasHeight=512 +canvas.width = canvasWidth; +canvas.height = canvasHeight; +squareSize=canvasWidth/8 +y=0 -var background = new Image(); -background.src = "board.png"; -// Make sure the image is loaded first otherwise nothing will draw. -background.onload = function(){ - ctx.drawImage(background,0,0); +for (x=0; x<=7; x+=1) +{ + if (x%2 == 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 != 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 == 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 != 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 == 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 != 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 == 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); +} +y+=1 +for (x=0; x<=8; x+=1) +{ + if (x%2 != 0){ + ctx.fillStyle="blue"} + else{ + ctx.fillStyle="red"} + ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); } -// draw whatever else over top of it on the canvas. +var wPieces=[] +var bPieces=[] + +var Piece=function(n, x, y, color, type) +{ +this.name=n; +this.x=x; +this.y=y; +this.color=color +this.type=type +this.selected=false +} + +var wKing = new Piece("White King", 64*4-32, 64/2, 'white',"K") +wPieces.push(wKing) +var wQueen=new Piece("White Queen", 64*5-32, 64/2, 'white',"Q") +wPieces.push(wQueen) +var bKing=new Piece("Black King", 64*4-32, canvasHeight-32, 'black', "K") +bPieces.push(bKing) +var bQueen=new Piece("Black Queen", 64*5-32, canvasHeight-32, 'black', "Q") +bPieces.push(bQueen) +redraw() + +function redraw(){ +for (i=0; i p.x-15 && my > p.y-15 && my < p.y+15) +{ +p.selected=true +found=true +selectedPiece=p +console.log(selectedPiece.name+" selected") +break; + +}//end of if whithin click range +}//end of loop through white pieces +if (found == false){ +for (i=0; i p.x-15 && my > p.y-15 && my < p.y+15) +{ +p.selected=true +selectedPiece=p +found=true +selectedPiece=p +console.log(p.name+" selected") +break; + +}//end of if whithin click range +}//end of loop through black pieces +}//end of if not found + +redraw() +} //end of click on canvas From b5298d6566a5b4e90872f2dbb8390726e15d9a7c Mon Sep 17 00:00:00 2001 From: AAA Date: Wed, 4 Oct 2017 17:10:10 -0500 Subject: [PATCH 06/25] Having problem with selecting piece --- client.html | 71 ++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/client.html b/client.html index 4e979ab..6e6abd2 100644 --- a/client.html +++ b/client.html @@ -218,42 +218,47 @@ }//end of drawCircle method -function selectPiece(){ -found=false -mx = event.offsetX; - my = event.offsetY; //offsetX, offsetY, may not work in older browsers, especially Firefox - - - for (i=0; i p.x-15 && my > p.y-15 && my < p.y+15) +function selectPiece() { -p.selected=true -found=true -selectedPiece=p -console.log(selectedPiece.name+" selected") -break; - -}//end of if whithin click range -}//end of loop through white pieces -if (found == false){ -for (i=0; i p.x-15 && my > p.y-15 && my < p.y+15) -{ -p.selected=true -selectedPiece=p -found=true -selectedPiece=p -console.log(p.name+" selected") -break; - -}//end of if whithin click range -}//end of loop through black pieces -}//end of if not found + found=false + mx = event.offsetX; + my = event.offsetY; //offsetX, offsetY, may not work in older browsers, especially Firefox + console.log(mx) + + for (i=0; i p.x-15 && my > p.y-15 && my < p.y+15) + { + p.selected=true + found=true + selectedPiece=p + console.log(selectedPiece.name+" selected") + break; + + }//end of if whithin click range + }//end of loop through white pieces + if (found == false) + { + for (i=0; i p.x-15 && my > p.y-15 && my < p.y+15) + { + p.selected=true + selectedPiece=p + found=true + selectedPiece=p + console.log(p.name+" selected") + break; + + }//end of if whithin click range + }//end of loop through black pieces + }//end of if not found redraw() -} //end of click on canvas +} //end of click on canvas function + From cc645473e172c713ee17401f0bc8d1402ae2174e Mon Sep 17 00:00:00 2001 From: AAA Date: Fri, 6 Oct 2017 15:41:48 -0500 Subject: [PATCH 07/25] make sure have latest code --- client.html | 83 +++++++---------------------------------------------- 1 file changed, 11 insertions(+), 72 deletions(-) diff --git a/client.html b/client.html index 6e6abd2..f7e1e83 100644 --- a/client.html +++ b/client.html @@ -80,80 +80,19 @@ squareSize=canvasWidth/8 y=0 +var black=false +for (var x = 0 ; x < 8 ; x++) { + for (var y = 0 ; y < 8 ; y++) { + console.log(x, y, (x*squareSize), (y*squareSize), black, ctx.fillStyle); + if (black) { ctx.fillStyle = "black"; } + else { ctx.fillStyle = "white"; } + ctx.fillRect(x*squareSize, y*squareSize, squareSize, squareSize); + black = !black; + } + black = !black +} - -for (x=0; x<=7; x+=1) -{ - if (x%2 == 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 != 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 == 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 != 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 == 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 != 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 == 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} -y+=1 -for (x=0; x<=8; x+=1) -{ - if (x%2 != 0){ - ctx.fillStyle="blue"} - else{ - ctx.fillStyle="red"} - ctx.fillRect(x*squareSize,y*squareSize,x*squareSize + squareSize, y*squareSize + squareSize); -} var wPieces=[] var bPieces=[] From 0d067516fb5a331053f32617b078f34b5f0036ad Mon Sep 17 00:00:00 2001 From: AAA Date: Sun, 8 Oct 2017 01:10:20 -0500 Subject: [PATCH 08/25] found mismatching }, canvas click still doesn't work --- client.html | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/client.html b/client.html index f7e1e83..09a70a4 100644 --- a/client.html +++ b/client.html @@ -68,22 +68,18 @@ log.innerHTML = escaped + "
" + log.innerHTML; } var selectedPiece=null; - - //Credit for canvas image draw https://stackoverflow.com/questions/14012768/html5-canvas-background-image +//Credit for canvas image draw https://stackoverflow.com/questions/14012768/html5-canvas-background-image var canvas = document.getElementById("myCanvas"), ctx = canvas.getContext("2d"); - canvasWidth=512 canvasHeight=512 canvas.width = canvasWidth; canvas.height = canvasHeight; - squareSize=canvasWidth/8 -y=0 var black=false for (var x = 0 ; x < 8 ; x++) { for (var y = 0 ; y < 8 ; y++) { - console.log(x, y, (x*squareSize), (y*squareSize), black, ctx.fillStyle); + //console.log(x, y, (x*squareSize), (y*squareSize), black, ctx.fillStyle); if (black) { ctx.fillStyle = "black"; } else { ctx.fillStyle = "white"; } ctx.fillRect(x*squareSize, y*squareSize, squareSize, squareSize); @@ -141,7 +137,7 @@ if (selectedPiece != null){ ctx.fillStyle="yellow" ctx.fillRect(selectedPiece.x-15, selectedPiece.y-15, selectedPiece.x+15, selectedPiece.y+15); - + }//end of if selectedPiece not null }//end of redraw function drawCircle(x,y, radius,color) @@ -162,7 +158,7 @@ found=false mx = event.offsetX; my = event.offsetY; //offsetX, offsetY, may not work in older browsers, especially Firefox - console.log(mx) + console.log("mouse pos: "+mx+", "+my) for (i=0; i From 309d44c971f1b614c72ade6bcc0298abda84c90d Mon Sep 17 00:00:00 2001 From: AAA Date: Mon, 9 Oct 2017 12:45:53 -0500 Subject: [PATCH 09/25] Merged PR from Clara --- client.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client.html b/client.html index 09a70a4..90316f5 100644 --- a/client.html +++ b/client.html @@ -137,8 +137,9 @@ if (selectedPiece != null){ ctx.fillStyle="yellow" ctx.fillRect(selectedPiece.x-15, selectedPiece.y-15, selectedPiece.x+15, selectedPiece.y+15); +}// end of if (selectedPiece !=null ){... }//end of if selectedPiece not null -}//end of redraw +//}//end of redraw function drawCircle(x,y, radius,color) { @@ -197,4 +198,4 @@ - + \ No newline at end of file From cbee4efdd4c8359cc58204e75814c730fbe69d83 Mon Sep 17 00:00:00 2001 From: AAA Date: Mon, 9 Oct 2017 21:53:11 -0500 Subject: [PATCH 10/25] selecting pieces works --- client.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client.html b/client.html index 90316f5..127fe78 100644 --- a/client.html +++ b/client.html @@ -11,7 +11,6 @@ -canvas.addEventListener('click', selectPiece);
@@ -75,6 +74,9 @@ canvasHeight=512 canvas.width = canvasWidth; canvas.height = canvasHeight; + + canvas.addEventListener('click', selectPiece); // but it will work here + squareSize=canvasWidth/8 var black=false for (var x = 0 ; x < 8 ; x++) { From e86198ad62c12f0ee8c738d2033a3a8162e5dbf5 Mon Sep 17 00:00:00 2001 From: AAA Date: Mon, 9 Oct 2017 22:15:42 -0500 Subject: [PATCH 11/25] added highlighted selected piece --- client.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client.html b/client.html index 127fe78..4224ed6 100644 --- a/client.html +++ b/client.html @@ -138,7 +138,9 @@ //draw selection indicator around piece selected if (selectedPiece != null){ ctx.fillStyle="yellow" - ctx.fillRect(selectedPiece.x-15, selectedPiece.y-15, selectedPiece.x+15, selectedPiece.y+15); + ctx.globalAlpha = 0.5; + ctx.fillRect(selectedPiece.x-squareSize/2, selectedPiece.y-squareSize/2, squareSize, squareSize); + ctx.globalAlpha = 1.0; }// end of if (selectedPiece !=null ){... }//end of if selectedPiece not null //}//end of redraw @@ -168,6 +170,9 @@ p=wPieces[i] if (mx < p.x+15 && mx > p.x-15 && my > p.y-15 && my < p.y+15) { + if (selectedPiece != null){ + selectedPiece.selected=false + } p.selected=true found=true selectedPiece=p From a20c9c2131db4532480bb60b96c691096fa02ae6 Mon Sep 17 00:00:00 2001 From: AAA Date: Mon, 9 Oct 2017 22:48:29 -0500 Subject: [PATCH 12/25] Added ability to move pieces with arrow keys --- client.html | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/client.html b/client.html index 4224ed6..1ce4f69 100644 --- a/client.html +++ b/client.html @@ -79,6 +79,7 @@ squareSize=canvasWidth/8 var black=false +function drawBoard(){ for (var x = 0 ; x < 8 ; x++) { for (var y = 0 ; y < 8 ; y++) { //console.log(x, y, (x*squareSize), (y*squareSize), black, ctx.fillStyle); @@ -89,7 +90,7 @@ } black = !black } - +}//end of drawBoard var wPieces=[] var bPieces=[] @@ -115,6 +116,15 @@ redraw() function redraw(){ +//clear canvas for redrawing +ctx.clearRect(0, 0, canvas.width, canvas.height); + +//redraw board +drawBoard() + + + + for (i=0; i= squareSize/2){ + selectedPiece.y-= squareSize + }//end of check if within board + }//end of if up + if (dir == 'down'){ + if (selectedPiece.y <= canvasHeight-squareSize/2){ + selectedPiece.y+=squareSize + }//end of if within board height + }//end of if down + if (dir == 'right'){ + if (selectedPiece.x<= canvasWidth-squareSize/2){ + selectedPiece.x+=squareSize + }//end of not go outside board + }//end of if right + if (dir == 'left'){ + if (selectedPiece.x >= squareSize/2){ + selectedPiece.x-=squareSize + }//end of within board + }//end of if left +}//end of if selectedPiece is not null +redraw() +}//end of movePiece method \ No newline at end of file From 506e92fb04906eeb18b5c24b36d1b2a5e14db002 Mon Sep 17 00:00:00 2001 From: AAA Date: Wed, 11 Oct 2017 20:07:55 -0500 Subject: [PATCH 13/25] added os.environ port --- server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.py b/server.py index e9106b5..d415386 100644 --- a/server.py +++ b/server.py @@ -1,4 +1,5 @@ from websocket_server import WebsocketServer +import os # Called for every client connecting (after handshake) def new_client(client, server): @@ -19,8 +20,7 @@ def message_received(client, server, message): server.send_message_to_all(message) - -PORT=9001 +port = int(os.environ.get("PORT", 5000)) server = WebsocketServer(PORT) server.set_fn_new_client(new_client) server.set_fn_client_left(client_left) From 2261a69041dc377a1ff7d75c811f89fb321e98db Mon Sep 17 00:00:00 2001 From: AAA Date: Sun, 15 Oct 2017 15:25:44 -0500 Subject: [PATCH 14/25] Added all pieces --- client.html | 44 ++++++++++++++++++++++++++++++++++++++++++++ setup.py | 15 --------------- 2 files changed, 44 insertions(+), 15 deletions(-) delete mode 100644 setup.py diff --git a/client.html b/client.html index 1ce4f69..63bd6ec 100644 --- a/client.html +++ b/client.html @@ -109,10 +109,54 @@ wPieces.push(wKing) var wQueen=new Piece("White Queen", 64*5-32, 64/2, 'white',"Q") wPieces.push(wQueen) +var wKnight1 = new Piece("White Knight", 64*3-32, squareSize/2, 'white', "K1") +wPieces.push(wKnight1) +var wKnight2 = new Piece('White Knight', 64*6-(squareSize/2), squareSize/2, 'white', "K2") +wPieces.push(wKnight2) +var wBishop1 = new Piece("White Bishop", 64*2-(squareSize/2), squareSize/2, 'white', "B1") +wPieces.push(wBishop1) +var wBishop2= new Piece("White Bishop", 64*7-(squareSize/2), squareSize/2, 'white', "B2") +wPieces.push(wBishop2) +var wRook1 = new Piece("White Rook", squareSize/2, squareSize/2, 'white', "R1") +wPieces.push(wRook1) +var wRook2 = new Piece("White Rook", squareSize*8-(squareSize/2), squareSize/2, 'white', "R2") +wPieces.push(wRook2) + +//White pons +for (var i=1; i<=8; i++) +{ + var wPon = new Piece("White Pon", squareSize*i-(squareSize/2), squareSize+squareSize/2, 'white', "P"+i) + wPieces.push(wPon) +}//end of for white pons + var bKing=new Piece("Black King", 64*4-32, canvasHeight-32, 'black', "K") bPieces.push(bKing) var bQueen=new Piece("Black Queen", 64*5-32, canvasHeight-32, 'black', "Q") bPieces.push(bQueen) +var bKnight1=new Piece("Black Knight", squareSize*3-(squareSize/2), canvasHeight-(squareSize/2), 'black', "K1") +bPieces.push(bKnight1) +var bKnight2=new Piece("Black Knight", squareSize*6-(squareSize/2), canvasHeight-(squareSize/2), 'black', "K2") +bPieces.push(bKnight2) +var bBishop1=new Piece("Black Bishop", squareSize*2-(squareSize/2), canvasHeight-(squareSize/2), 'black', "B1") +bPieces.push(bBishop1) +var bBishop2=new Piece("Black Bishop", squareSize*7-(squareSize/2), canvasHeight-(squareSize/2), 'black', "B2") +bPieces.push(bBishop2) +var bRook1=new Piece("Black Rook", squareSize*1-(squareSize/2), canvasHeight-(squareSize/2), 'black', "R1") +bPieces.push(bRook1) +var bRook2=new Piece("Black Rook", squareSize*8-(squareSize/2), canvasHeight-(squareSize/2), 'black', "R2") +bPieces.push(bRook2) + + + + + +//Black pons +for (var i=1; i<=8; i++) +{ + var bPon = new Piece("Black Pon", squareSize*i-(squareSize/2), canvasHeight-(squareSize+squareSize/2), 'white', "P"+i) + bPieces.push(bPon) +}//end of for black pons + redraw() function redraw(){ diff --git a/setup.py b/setup.py deleted file mode 100644 index b495e1b..0000000 --- a/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -from setuptools import setup, find_packages - -setup( - name='websocket_server', - version='0.4', - packages=find_packages("."), - url='https://github.com/Pithikos/python-websocket-server', - license='MIT', - author='Johan Hanssen Seferidis', - author_email='manossef@gmail.com', - install_requires=[ - ], - description='A simple fully working websocket-server in Python with no external dependencies', - platforms='any', -) From 2e0f89e6d10ac5dd899785c8c012cc79b8a151f7 Mon Sep 17 00:00:00 2001 From: AAA Date: Sun, 15 Oct 2017 21:13:06 -0500 Subject: [PATCH 15/25] can move pieces across web socket --- client.html | 46 ++++++++++++++++++++++++++++++++++++++++++---- server.py | 2 +- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/client.html b/client.html index 63bd6ec..9a863a2 100644 --- a/client.html +++ b/client.html @@ -24,7 +24,7 @@ function init() { // Connect to Web Socket - ws = new WebSocket("ws://localhost:9001/"); + ws = new WebSocket("ws://localhost:5000/"); // Set event handlers. ws.onopen = function() { @@ -33,7 +33,8 @@ ws.onmessage = function(e) { // e.data contains received string. - output("" + e.data); + processMovePiece(e.data) + output("" + e.data); }; ws.onclose = function() { @@ -51,7 +52,8 @@ var input = document.getElementById("input"); // You can send message to the Web Socket using ws.send. ws.send(input.value); - output("send: " + input.value); + + output("send: " + input.value); input.value = ""; input.focus(); } @@ -61,7 +63,8 @@ } function output(str) { - var log = document.getElementById("log"); + console.log("output: "+str) + var log = document.getElementById("log"); var escaped = str.replace(/&/, "&").replace(//, ">").replace(/"/, """); // " log.innerHTML = escaped + "
" + log.innerHTML; @@ -280,6 +283,7 @@ if (dir == 'up'){ if (selectedPiece.y >= squareSize/2){ selectedPiece.y-= squareSize + }//end of check if within board }//end of if up if (dir == 'down'){ @@ -298,8 +302,42 @@ }//end of within board }//end of if left }//end of if selectedPiece is not null + +ws.send("movePiece "+selectedPiece.type+" "+selectedPiece.x+" "+selectedPiece.y) redraw() }//end of movePiece method + +function getPieceByType(string){ + for (var i=0; i<=wPieces.length; i++){ + if (wPieces[i].type == string){ + return wPieces[i] + break + } + }//end of loop through white pieces + + for (var i=0; i<=bPieces.length; i++){ + if (bPieces[i].type == string){ + return bPieces[i] + break + } + + + }//end of loop through black pieces + +}//end of function getPieceByType + +function processMovePiece(string){ + var stringArray = string.split(" ") + if (stringArray[0] == "movePiece"){ + p=getPieceByType(stringArray[1]) + //console.log(p.name+" moved.") + p.x = parseInt(stringArray[2]) + p.y=parseInt(stringArray[3]) + redraw() + }//end of if stringArray[0] == movePiece + +}//end of processMovePiece + \ No newline at end of file diff --git a/server.py b/server.py index d415386..ee226d1 100644 --- a/server.py +++ b/server.py @@ -20,7 +20,7 @@ def message_received(client, server, message): server.send_message_to_all(message) -port = int(os.environ.get("PORT", 5000)) +PORT = int(os.environ.get("PORT", 5000)) server = WebsocketServer(PORT) server.set_fn_new_client(new_client) server.set_fn_client_left(client_left) From b6e590a2f9618621a0abfcf83c8547be7a7a197b Mon Sep 17 00:00:00 2001 From: AAA Date: Mon, 16 Oct 2017 14:24:32 -0500 Subject: [PATCH 16/25] Fixed move pieces, now works across sockets --- client.html | 157 +++++++++++++++++++++++++++++++++++++--------------- server.py | 3 +- 2 files changed, 115 insertions(+), 45 deletions(-) diff --git a/client.html b/client.html index 9a863a2..b960c20 100644 --- a/client.html +++ b/client.html @@ -18,7 +18,7 @@ \ No newline at end of file From 7bb08b65bb41d53d4b6701575cad0f03daaf0488 Mon Sep 17 00:00:00 2001 From: AAA Date: Tue, 17 Oct 2017 11:43:46 -0500 Subject: [PATCH 21/25] Fixed white pieces turning black on capture --- client.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.html b/client.html index 8cd23b5..1fc1529 100644 --- a/client.html +++ b/client.html @@ -438,7 +438,7 @@ //this function checks if two pieces are at the same position function collision(){ - if (selectedPiece.color='black'){ + if (selectedPiece.color == 'black'){ for (var i =0; i Date: Tue, 17 Oct 2017 12:05:01 -0500 Subject: [PATCH 22/25] capture positions now work --- README.md | 113 +++------------------------------------------------- board.png | Bin 28204 -> 0 bytes client.html | 4 +- 3 files changed, 7 insertions(+), 110 deletions(-) delete mode 100644 board.png diff --git a/README.md b/README.md index c2a2c97..b37cc7b 100644 --- a/README.md +++ b/README.md @@ -1,110 +1,7 @@ -Websocket Server -======================= +#Web Chess +This application uses a python web socket to play a game of chess. There can be multiple clients connected and each has access to the game board to move any piece. This allows for flexibility in how you play. Messages are broadcast to all clients in the chat area to the left. Clicking on a game piece will select it and using the arrow keys will move the piece. When the selected piece collides with a piece of the opposite color, that piece is removed from play 'captured'. -A minimal Websockets Server in Python with no external dependencies. +Notes: I am currently unable to deploy this application to heroku or Python Anywhere so it just runs locally for now. - * Works with Python2 and Python3 - * Clean simple API - * Multiple clients - * No dependencies - -Notice that this implementation does not support the more advanced features -like SSL etc. The project is focused mainly on making it easy to run a -websocket server for prototyping, testing or for making a GUI for your application. - -If this project reduced your development time feel free to buy me a coffee. - -[![Donate](https://www.paypal.com/en_US/i/btn/x-click-but21.gif)](https://www.paypal.me/seferidis) - - -Usage -======================= -You can get a feel of how to use the websocket server by running - - python server.py - -Then just open `client.html` in your browser and you should be able to send and receive messages. - - -Using in your project -======================= - -You can use the project in three ways. - - 1. Copy/paste the *websocket_server.py* file in your project and use it directly - 2. `pip install git+https://github.com/Pithikos/python-websocket-server` (latest code) - 3. `pip install websocket-server` (might not be up-to-date) - -For coding details have a look at the [*server.py*](https://github.com/Pithikos/python-websocket-server/blob/master/server.py) example and the [API](https://github.com/Pithikos/python-websocket-server#api). - - -API -======================= - -The API is simply methods and properties of the `WebsocketServer` class. - -## WebsocketServer - -The WebsocketServer can be initialized with the below parameters. - -*`port`* - The port clients will need to connect to. - -*`host`* - By default the `127.0.0.1` is used which allows connections only from the current machine. If you wish to allow all network machines to connect, you need to pass `0.0.0.0` as hostname. - -*`loglevel`* - logging level to print. By default WARNING is used. You can use `logging.DEBUG` or `logging.INFO` for more verbose output. - - -### Properties - -| Property | Description | -|----------|----------------------| -| clients | A list of `client` | - - -### Methods - -| Method | Description | Takes | Gives | -|-----------------------------|---------------------------------------------------------------------------------------|-----------------|-------| -| `set_fn_new_client()` | Sets a callback function that will be called for every new `client` connecting to us | function | None | -| `set_fn_client_left()` | Sets a callback function that will be called for every `client` disconnecting from us | function | None | -| `set_fn_message_received()` | Sets a callback function that will be called when a `client` sends a message | function | None | -| `send_message()` | Sends a `message` to a specific `client`. The message is a simple string. | client, message | None | -| `send_message_to_all()` | Sends a `message` to **all** connected clients. The message is a simple string. | message | None | - - -### Callback functions - -| Set by | Description | Parameters | -|-----------------------------|---------------------------------------------------|-------------------------| -| `set_fn_new_client()` | Called for every new `client` connecting to us | client, server | -| `set_fn_client_left()` | Called for every `client` disconnecting from us | client, server | -| `set_fn_message_received()` | Called when a `client` sends a `message` | client, server, message | - - -The client passed to the callback is the client that left, sent the message, etc. The server might not have any use to use. However it is passed in case you want to send messages to clients. - - -Example: -```` -import logging -from websocket_server import WebsocketServer - -def new_client(client, server): - server.send_message_to_all("Hey all, a new client has joined us") - -server = WebsocketServer(13254, host='127.0.0.1', loglevel=logging.INFO) -server.set_fn_new_client(new_client) -server.run_forever() -```` - -## Client - -Client is just a dictionary passed along methods. - -```` -{ - 'id' : client_id, - 'handler' : client_handler, - 'address' : (addr, port) -} -```` +#How to run: +In a command prompt, navigate to the folder containing server.py and run the server using 'python server.py'. A message should appear stating that the server is running. You can then open up as many client.html windows as you want. Any message or piece movement will be sent to all connected clients. To stop the server, in the command prompt, press control+c and type 'exit'. \ No newline at end of file diff --git a/board.png b/board.png deleted file mode 100644 index c8b310f86e4dfac53417365d141dee270554f8a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28204 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 b>Xg_1h>QIfV!=1O!A_lY_`cl6_vZfqi;{%a diff --git a/client.html b/client.html index 1fc1529..7b2c8b0 100644 --- a/client.html +++ b/client.html @@ -134,9 +134,9 @@ this.captured=false this.captureX = x if (color == 'black'){ -this.captureY = y-canvasHeight +this.captureY = y-canvasHeight+(squareSize*4) }else{ -this.captureY = y+canvasHeight +this.captureY = y+canvasHeight-(squareSize*4) }//end of if color is not white } From 21dd9d0435f3618df047d0e2c1eb3680c5d4aa12 Mon Sep 17 00:00:00 2001 From: AAA Date: Tue, 17 Oct 2017 12:24:09 -0500 Subject: [PATCH 23/25] trying get send selectedPiece working --- client.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client.html b/client.html index 7b2c8b0..0dd3e92 100644 --- a/client.html +++ b/client.html @@ -45,7 +45,13 @@ ws.onmessage = function(e) { // e.data contains received string. processMovePiece(e.data) + var firstWord=e.data.split(' ') + + //console.log(firstWord[0]) + //don't want to print move commands + if (firstWord[0] != 'movePiece'){ output("" + e.data); + } }; ws.onclose = function() { From 62ae5d73186995f25108c05999a7f1be7b7eb169 Mon Sep 17 00:00:00 2001 From: AAA Date: Tue, 17 Oct 2017 12:40:43 -0500 Subject: [PATCH 24/25] selected piece on other clients does not capture pieces --- client.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client.html b/client.html index 0dd3e92..38def0f 100644 --- a/client.html +++ b/client.html @@ -46,10 +46,15 @@ // e.data contains received string. processMovePiece(e.data) var firstWord=e.data.split(' ') - +if (firstWord[0] == 'selectedPiece'){ +var p=getPieceByType(firstWord[1], firstWord[2]) +selectedPiece=p +p.selected=true +redraw() +} //console.log(firstWord[0]) //don't want to print move commands - if (firstWord[0] != 'movePiece'){ + if (firstWord[0] != 'movePiece' || firstWord[0] == 'selectedPiece'){ output("" + e.data); } }; @@ -320,6 +325,7 @@ p.selected=true found=true selectedPiece=p + ws.send('selectedPiece '+selectedPiece.color+' '+selectedPiece.type) console.log(selectedPiece.name+" selected"+selectedPiece.color) break; From 164a9b686921e9db4c34c513804bd6f97a9d488b Mon Sep 17 00:00:00 2001 From: AAA Date: Tue, 17 Oct 2017 20:20:01 -0500 Subject: [PATCH 25/25] edited readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b37cc7b..18397fd 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,7 @@ This application uses a python web socket to play a game of chess. There can be Notes: I am currently unable to deploy this application to heroku or Python Anywhere so it just runs locally for now. #How to run: -In a command prompt, navigate to the folder containing server.py and run the server using 'python server.py'. A message should appear stating that the server is running. You can then open up as many client.html windows as you want. Any message or piece movement will be sent to all connected clients. To stop the server, in the command prompt, press control+c and type 'exit'. \ No newline at end of file +In a command prompt, navigate to the folder containing server.py and run the server using 'python server.py'. A message should appear stating that the server is running. You can then open up as many client.html windows as you want. Any message or piece movement will be sent to all connected clients. To stop the server, in the command prompt, press control+c and type 'exit'. + +#Known Issues +Selected piece on other clients do not capture pieces like what happens on the client that is controlling the selected piece. \ No newline at end of file