Added python tictactoe client

This commit is contained in:
Jonatan Pålsson 2011-05-16 12:48:58 +02:00
parent 9efd739cbb
commit f81fec6b9c
6 changed files with 706 additions and 1 deletions

@ -1 +1 @@
Subproject commit 00312859714bef6e9a4fdb9931a41fef56eeb89a
Subproject commit a94993dc5a626605bdf45c45f398270fe33eaaf1

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy project-wide -->
<widget class="GtkWindow" id="window1">
<property name="width_request">561</property>
<property name="height_request">521</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;span size="x-large"&gt;GGS Killtrolpanel&lt;/span&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="pixbuf">kill_process_icon.jpg</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="homogeneous">True</property>
<child>
<widget class="GtkButton" id="playersButton">
<property name="label" translatable="yes">All players</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_playersButton_clicked"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="coordinatorButton">
<property name="label" translatable="yes">Coordinator</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_coordinatorButton_clicked"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dispatcherButton">
<property name="label" translatable="yes">Dispatcher</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_dispatcherButton_clicked"/>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="coordinatorBackupButton">
<property name="label" translatable="yes">Coordinator backup</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_coordinatorBackupButton_clicked"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="tablesButton">
<property name="label" translatable="yes">All tables</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_tablesButton_clicked"/>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="gamevmButton">
<property name="label" translatable="yes">All GameVMs</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_gamevmButton_clicked"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -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()

View file

@ -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;
}

View file

@ -0,0 +1,248 @@
<?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy project-wide -->
<widget class="GtkWindow" id="window1">
<property name="width_request">561</property>
<property name="height_request">521</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="ypad">7</property>
<property name="label" translatable="yes">&lt;span size="x-large"&gt;GGS-Pong&lt;/span&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">3</property>
<property name="homogeneous">True</property>
<child>
<widget class="GtkButton" id="x0y0">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x0y0_clicked" swapped="no"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="x1y0">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x1y0_clicked" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x0y1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x0y1_clicked" swapped="no"/>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x1y1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x1y1_clicked" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x0y2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x0y2_clicked" swapped="no"/>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x1y2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x1y2_clicked" swapped="no"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x2y0">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x2y0_clicked" swapped="no"/>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x2y1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x2y1_clicked" swapped="no"/>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="x2y2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_x2y2_clicked" swapped="no"/>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkEntry" id="adress">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="text" translatable="yes">ggs.jeena.net:9000</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="token">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="connectBtn">
<property name="label" translatable="yes">☎</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_connectBtn_clicked" swapped="no"/>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -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()