From f81fec6b9c9f7a5de5a956d45192d458127dda1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Mon, 16 May 2011 12:48:58 +0200 Subject: [PATCH] Added python tictactoe client --- doc/report | 2 +- games/tic-tac-toe-python/ggskpanel.glade | 135 ++++++++++++ games/tic-tac-toe-python/kpanel.py | 44 ++++ games/tic-tac-toe-python/server.js | 156 ++++++++++++++ games/tic-tac-toe-python/ttt.glade | 248 +++++++++++++++++++++++ games/tic-tac-toe-python/ttt.py | 122 +++++++++++ 6 files changed, 706 insertions(+), 1 deletion(-) create mode 100644 games/tic-tac-toe-python/ggskpanel.glade create mode 100644 games/tic-tac-toe-python/kpanel.py create mode 100644 games/tic-tac-toe-python/server.js create mode 100644 games/tic-tac-toe-python/ttt.glade create mode 100644 games/tic-tac-toe-python/ttt.py diff --git a/doc/report b/doc/report index 0031285..a94993d 160000 --- a/doc/report +++ b/doc/report @@ -1 +1 @@ -Subproject commit 00312859714bef6e9a4fdb9931a41fef56eeb89a +Subproject commit a94993dc5a626605bdf45c45f398270fe33eaaf1 diff --git a/games/tic-tac-toe-python/ggskpanel.glade b/games/tic-tac-toe-python/ggskpanel.glade new file mode 100644 index 0000000..3f85df9 --- /dev/null +++ b/games/tic-tac-toe-python/ggskpanel.glade @@ -0,0 +1,135 @@ + + + + + + 561 + 521 + + + True + + + True + + + True + <span size="x-large">GGS Killtrolpanel</span> + True + + + False + 0 + + + + + True + kill_process_icon.jpg + + + False + False + 1 + + + + + False + False + 0 + + + + + True + 3 + 2 + True + + + All players + True + True + True + + + + + + Coordinator + True + True + True + + + + 1 + 2 + + + + + Dispatcher + True + True + True + + + + 1 + 2 + + + + + Coordinator backup + True + True + True + + + + 1 + 2 + 1 + 2 + + + + + All tables + True + True + True + + + + 2 + 3 + + + + + All GameVMs + True + True + True + + + + 1 + 2 + 2 + 3 + + + + + 1 + + + + + + diff --git a/games/tic-tac-toe-python/kpanel.py b/games/tic-tac-toe-python/kpanel.py new file mode 100644 index 0000000..84fb5e1 --- /dev/null +++ b/games/tic-tac-toe-python/kpanel.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +import sys, socket, thread, gobject, getpass, time, os +try: + import pygtk + pygtk.require("2.16") +except: + pass +try: + import gtk + import gtk.glade +except: + sys.exit(1) + +class GGSKPanel: + + def __init__(self): + #Set the Glade file + self.gladefile = "ttt.glade" + self.wTree = gtk.glade.XML(self.gladefile, "window1") + + #Create our dictionay and connect it + dic = { "on_window1_destroy_event" : gtk.main_quit + ,"on_coordinatorButton_clicked" : lambda x: self.terminateProcess("ggs_coordinator") + ,"on_coordinatorBackupButton_clicked" :\ + lambda x: self.terminateProcess("ggs_coordinator_backup") + ,"on_dispatcherButton_clicked" : lambda x: self.terminateProcess("ggs_dispatcher") + } + + self.wTree.signal_autoconnect(dic) + + self.wTree.get_widget("window1").show() + + def terminateProcess(self, process): + os.system("echo \"exit(whereis(%s), 'Bye bye').\" | erl_call -sname ggs -e" % process) + + def setStatus(self, msg): + self.wTree.get_widget("statusbar").push(0, msg) + + +if __name__ == "__main__": + chat = GGSKPanel() + gobject.threads_init() + gtk.main() diff --git a/games/tic-tac-toe-python/server.js b/games/tic-tac-toe-python/server.js new file mode 100644 index 0000000..d98eaf7 --- /dev/null +++ b/games/tic-tac-toe-python/server.js @@ -0,0 +1,156 @@ +function playerCommand(player_id, command, args) { + if (commaned == "hi") { + hi(player_id); + } else if (command == "set") { + move(player_id, args); + } else if (command == "new") { + newGame(); + } +} + +var ROWS = 3; + +function hi(player_id) { + var p1_id = GGS.localStorage.getItem("p1_id"); + var p2_id = GGS.localStorage.getItem("p2_id"); + if (p1_id == "") { + GGS.localStorage.setItem("p1_id", player_id); + GGS.sendCommand(player_id, "welcome", "1"); + } else if (p2_id == "") { + GGS.localStorage.setItem("p2_id", player_id); + GGS.sendCommand(player_id, "welcome", "2"); + } else { + GGS.sendCommand(player_id, "not_welcome", "Already have 2 players on this table"); + } +} + +function move(player_id, args) { + var nextPlayer = GGS.localStorage.getItem("next_player"); + var p1_id = GGS.localStorage.getItem("p1_id"); + var p2_id = GGS.localStorage.getItem("p2_id"); + var valid = false; + + if(nextPlayer == 1 && player_id == p1_id) { + valid = true; + } else if (nextPlayer == 2 && player_id == p2_id) { + valid = true; + } + + if (valid) { + + var p = nextPlayer; + var props = JSON.parse(args); + var gameBoard = JSON.parse(GGS.localStorage.getItem("game_board")); + + if (gameBoard[props.x][props.y] == 0) { + + gameBoard[props.x][props.y] = p; + GGS.localStorage.setItem("game_board", JSON.stringify(gameBoard)); + GGS.sendCommandToAll("game_board", boardAsString(gameBoard)); + + if (this.checkIfWon(p, gameBoard)) { + if (p == 1) { + GGS.sendCommand(p1_id, "winner", "You win!"); + GGS.sendCommand(p2_id, "loser", "You lose!"); + } else { + GGS.sendCommand(p1_id, "loser", "You lose!"); + GGS.sendCommand(p2_id, "winner", "You win!"); + } + } + + if (nextPlayer == 1) { + GGS.localStorage.setItem("next_player", 2); + GGS.sendCommand(p1_id, "yourturn", ""); + } else { + GGS.localStorage.setItem("next_player", 1); + GGS.sendCommand(p2_id, "yourturn", ""); + } + + } else { + GGS.sendCommand(plaer_id, "warning", "Already set, chose something else."); + } + + } else { + GGS.sendCommand(player_id, "warning", "Not your turn!"); + } +} + +function checkIfWon(player) { + + var gameBoard = JSON.parse(GGS.localStorage.getItem("game_board")); + + for (i = 0; i < ROWS; ++i) { + for (j = 0; j < ROWS; ++j) { + if (gameBoard[i][j] != 'X') { + break; + } + } + if (j == ROWS) { + return true; + } + + for (j = 0; j < ROWS; ++j) { + if (gameBoard[j][i] != 'X') { + break; + } + } + if (j == ROWS) { + return true; + } + } + + // Now check diagnols + for (i = 0; i < ROWS; ++i) { + if (gameBoard[i][i] != 'X') { + break; + } + } + + if (i == ROWS) { + return true; + } + + for (i = 0; i < ROWS; ++i) { + if (gameBoard[i][ROWS - i - 1] != 'X') { + break; + } + } + if (i == ROWS) { + return true; + } + + return false; +} + +function newGame() { + // Initiate game with empty rows and columns + var gameBoard = []; + for (var i=0; i < ROWS; i++) { + gameBoard[i] = []; + for (var j=0; i < ROWS; i++) { + gameBoard[i][j] = ''; + } + } + + GGS.localStorage.setItem("game_board", JSON.stringify(gameBoard)); + GGS.sendCommandToAll("new_game", ""); + GGS.sendCommandToAll("game_board", boardAsString(gameBoard)); +} + +function boardAsString(gameBoard) { + var out = ""; + for (var i=0; i < ROWS; i++) { + for (var j=0; j < ROWS; j++) { + var p = gameBoard[i][j]; + if (p == 1) { + out += "X"; + } else if (p == 2) { + out +="O"; + } else { + out += " "; + } + } + } + + return out; +} diff --git a/games/tic-tac-toe-python/ttt.glade b/games/tic-tac-toe-python/ttt.glade new file mode 100644 index 0000000..4b3025d --- /dev/null +++ b/games/tic-tac-toe-python/ttt.glade @@ -0,0 +1,248 @@ + + + + + + 561 + 521 + False + + + True + False + + + True + False + + + True + False + 7 + <span size="x-large">GGS-Pong</span> + True + + + True + False + 0 + + + + + False + False + 0 + + + + + True + False + 3 + 3 + True + + + True + True + True + False + + + + + + True + True + True + False + + + + 1 + 2 + + + + + True + True + True + False + + + + 1 + 2 + + + + + True + True + True + False + + + + 1 + 2 + 1 + 2 + + + + + True + True + True + False + + + + 2 + 3 + + + + + True + True + True + False + + + + 1 + 2 + 2 + 3 + + + + + True + True + True + False + + + + 2 + 3 + + + + + True + True + True + False + + + + 2 + 3 + 1 + 2 + + + + + True + True + True + False + + + + 2 + 3 + 2 + 3 + + + + + True + True + 1 + + + + + True + False + + + True + True + + ggs.jeena.net:9000 + True + False + False + True + True + + + True + True + 0 + + + + + True + True + + False + False + True + True + + + True + True + 1 + + + + + + True + True + True + False + + + + True + True + 2 + + + + + False + True + 2 + + + + + True + False + 2 + + + False + True + 3 + + + + + + diff --git a/games/tic-tac-toe-python/ttt.py b/games/tic-tac-toe-python/ttt.py new file mode 100644 index 0000000..06ef9bd --- /dev/null +++ b/games/tic-tac-toe-python/ttt.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python + +import sys, socket, thread, gobject, getpass, time, os +try: + import pygtk + pygtk.require("2.16") +except: + pass +try: + import gtk + import gtk.glade +except: + sys.exit(1) + +class GGSTTT: + + def __init__(self): + #Set the Glade file + self.gladefile = "ttt.glade" + self.wTree = gtk.glade.XML(self.gladefile, "window1") + host = "localhost" + port = 9000 + + #Create our dictionay and connect it + dic = { "on_window1_destroy_event" : gtk.main_quit + ,"on_x0y0_clicked" : lambda x: self.sendMove("{'x':0,'y':0}") + ,"on_x0y1_clicked" : lambda x: self.sendMove("{'x':0,'y':1}") + ,"on_x0y2_clicked" : lambda x: self.sendMove("{'x':0,'y':2}") + ,"on_x1y0_clicked" : lambda x: self.sendMove("{'x':1,'y':0}") + ,"on_x1y1_clicked" : lambda x: self.sendMove("{'x':1,'y':1}") + ,"on_x1y2_clicked" : lambda x: self.sendMove("{'x':1,'y':2}") + ,"on_x2y0_clicked" : lambda x: self.sendMove("{'x':2,'y':0}") + ,"on_x2y1_clicked" : lambda x: self.sendMove("{'x':2,'y':1}") + ,"on_x2y2_clicked" : lambda x: self.sendMove("{'x':2,'y':2}") + ,"on_connectBtn_clicked" : lambda x: self.doConnect() + } + + self.wTree.signal_autoconnect(dic) + + self.wTree.get_widget("window1").show() + + def doConnect(self): + self.setStatus("Not connected") + hostport = self.wTree.get_widget("adress").get_text() + host, port = hostport.split(":") + + self.connect(host, int(port)) + thread.start_new_thread(self.listen, ()) + + token = self.wTree.get_widget("token").get_text() + self.s.send("Server-Command: hello\n" + + "Content-Type: text\n" + + "Content-Length: %s\n" % len(token)+ + "\n"+ + token) + self.s.send("Game-Command: hi\n" + + "Content-Type: text\n" + + "Content-Length: 0\n"+ + "\n") + + def sendMove(self, move): + print "Sending move", move + cmd = "set" + self.s.send("Game-Command: %s\n" % cmd + + "Content-Type: text\n" + + "Content-Length: %s\n" % len(move)+ + "\n"+ + move) + + def setStatus(self, msg): + self.wTree.get_widget("statusbar").push(0, msg) + + def listen(self): + msg = {} + print "listening" + fs = self.s.makefile() + while True: + line = fs.readline() + print "Received: '%s" % line.strip() + if line != "\n": + key = line.split(":")[0] + value = line.split(":")[1] + msg[key] = value.strip() + else: + msg["DATA"] = fs.read(int("%s" % msg["Content-Size"])) + print "Got data:", msg + self.protocolHandler(msg) + + def protocolHandler(self, msg): + if msg["Client-Command"] == "hello": + data = msg["DATA"] + self.token, defined, table_token = data.split(",") + if defined == "false": + print "Defining game" + js = open("server.js").read() + self.s.send("Server-Command: define\n"+ + "Content-Type: text\n" + + ("Content-Length: %s\n" % len(js))+ + "\n%s" % js) + + elif msg["Client-Command"] == "welcome": + self.setStatus("You are player %s" % msg["data"]) + elif msg["Client-Command"] == "chat": + gobject.idle_add(self.updateChatText, msg["DATA"]) + elif msg["Client-Command"] == "lusers": + print msg + gobject.idle_add(self.updateUsers, msg["DATA"]) + + def connect(self, host,port): + print "Connecting" + self.setStatus("Connecting") + self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.s.connect((host, port)) + self.setStatus("Connected!") + + + + +if __name__ == "__main__": + ttt = GGSTTT() + gobject.threads_init() + gtk.main()