My first python project =)

This is a discussion on My first python project =) within the Tech Board forums, part of the Community Boards category; Alright guys. Since ASM has failed on me, I tried giving a shot at Python. I've tried writing a tic-tac-toe ...

My first python project =)

Alright guys. Since ASM has failed on me, I tried giving a shot at Python. I've tried writing a tic-tac-toe game and I ended up succeeding in 30-45 minutes ! That's not quite bad as I read documentation for about 15-20 minutes only ! =D

Here's the code. It must be pretty darn ugly code... but still, it compiles and works as intended.

Code:

symbols = { 0:' ', 1:'x', 2:'o' }
table = [0,0,0,0,0,0,0,0,0]
wantsToPlay = 'y'
def displayTable(table):
for i in range(len(table)):
if (i+1)&#37;3 is 0:
print symbols[table[i]]
else:
print symbols[table[i]], '|',
def resetTable(table):
for i in range(len(table)):
table[i] = 0
def isWinner(table, player):
if (table[0] is player and table[1] is player and table[2] is player) or \
(table[3] is player and table[4] is player and table[5] is player) or \
(table[6] is player and table[7] is player and table[8] is player) or \
(table[0] is player and table[3] is player and table[6] is player) or \
(table[1] is player and table[4] is player and table[7] is player) or \
(table[2] is player and table[5] is player and table[8] is player) or \
(table[0] is player and table[4] is player and table[8] is player) or \
(table[2] is player and table[4] is player and table[6] is player):
return 1
else:
return 0
while(wantsToPlay is 'y'):
resetTable(table)
playerTurn = 2
while(isWinner(table, 1) is not 1 and isWinner(table, 2) is not 1):
displayTable(table)
playerTurn = (2 - playerTurn) + 1
while 1 is 1:
coord = int(raw_input("What coord do you want to play ? (0-8) "))
if table[coord] is 0:
table[coord] = playerTurn
break
print "Congratulations player %d you have won !" % (playerTurn)
wantsToPlay = raw_input("Do you want to play again ? (y/n) ")

Last edited by Desolation; 06-17-2007 at 11:46 PM.
Reason: Used a dictionary for symbols and moved globals up at the top.

And the only reason I bourght up the spaces is that at one time I'd made this Sudoku game in python which had like 20 or some classes with someone else. The problem was that mine and her coding styles conflicted, namely on the aspect that she used spaces for her code, and I used tabs. Which, when we were develloping on the Linux platform, seemd ok because everything was lining up correctly. But then, when we moved to windows, the size of the tabs changed, and all of our code was broken, and we had to go through like 3 hours of refactoring. Since then, I've been reluctant to use anything but spaces in my indentation.

I have added more meat to it, I wanted it to be multi-player, but I can't test it right now... I've coded it but I am behind a router... and I can't forward ports because my father's girlfriend has changed the router's login and password... MEH ! Here's the code though, don't be shy and tell me if something's wrong with it.

Code:

import socket
# turnInfo is used to know wether the current application is
# player 1 (host) or player 2 (client)
turnInfo = { 'y':1, 'n':2 }
# symbols is used to display the status of the game table
symbols = { 0:' ', 1:'x', 2:'o' }
# The game table is represented by a serie of zeros (empty),
# ones (player 1) and twos (player 2)
table = [0,0,0,0,0,0,0,0,0]
wantsToPlay = 'y'
port = 1234
host = "127.0.0.1"
def displayTable(table):
for i in range(len(table)):
if (i+1)&#37;3 is 0:
print symbols[table[i]]
else:
print symbols[table[i]], '|',
def resetTable(table):
for i in range(len(table)):
table[i] = 0
def isWinner(table, player):
if (table[0] is player and table[1] is player and table[2] is player) or \
(table[3] is player and table[4] is player and table[5] is player) or \
(table[6] is player and table[7] is player and table[8] is player) or \
(table[0] is player and table[3] is player and table[6] is player) or \
(table[1] is player and table[4] is player and table[7] is player) or \
(table[2] is player and table[5] is player and table[8] is player) or \
(table[0] is player and table[4] is player and table[8] is player) or \
(table[2] is player and table[4] is player and table[6] is player):
return 1
else:
return 0
# Initialize socket and decide who is the server
discussionSocket = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
isHost = raw_input("Is this the server side ? (y/n) ")
# If current application is host, bind socket and listen for connection
if isHost is 'y':
s.bind(("127.0.0.1", port))
s.listen(1)
discussionSocket, addr = s.accept()
print "Successfully connected to %s" % (addr)
# Otherwise, try connecting to host
else:
if s.connect_ex((host, port)) is 0:
print "Successfully connected to host"
discussionSocket = s
while(wantsToPlay is 'y'):
resetTable(table)
# We start with player one, so we need to set playerTurn as 2
playerTurn = 2
# While nobody wins
while(isWinner(table, 1) is not 1 and isWinner(table, 2) is not 1):
displayTable(table)
# Change player turn. This trick recquired playerTurn to be set as 2 previously
# in order to start the game with player 1
playerTurn = (2 - playerTurn) + 1
# If current application matches player turn (host = 1, client = 2)
if turnInfo[isHost] is playerTurn:
# Wait until the player has entered a valid input
while 1 is 1:
coord = int(raw_input("What coord do you want to play ? (0-8) "))
if table[coord] is 0:
table[coord] = playerTurn
discussionSocket.send(coord)
break
# Otherwise, wait for distant player's move
else:
answer = discussionSocket.recv(4)
table[int(answer)] = playerTurn
print "Congratulations player %d you have won !" % (playerTurn)
wantsToPlay = raw_input("Do you want to play again ? (y/n) ")

Thanks for that note ! Ah ah, it was only to practice the language though so it doesn't matter if there's a logical error like that ;-)

Here's my second project, it's only a rough draft and is very limited in features, but it works as intended. I simply write a band name and a song name and my program fetches me the tab and saves it on a file =D

Welcome to the obsession, er, language. For a first attempt, you've got a pretty Pythonic style. Not too ugly at all. Congrats!

Originally Posted by Desolation

Code:

def isWinner(table, player):
if (table[0] is player and table[1] is player and table[2] is player) or \
(table[3] is player and table[4] is player and table[5] is player) or \
(table[6] is player and table[7] is player and table[8] is player) or \
(table[0] is player and table[3] is player and table[6] is player) or \
(table[1] is player and table[4] is player and table[7] is player) or \
(table[2] is player and table[5] is player and table[8] is player) or \
(table[0] is player and table[4] is player and table[8] is player) or \
(table[2] is player and table[4] is player and table[6] is player):
return 1
else:
return 0

Might I suggest a slightly more efficient form of this, that you might not be aware of:

Also, do you know why the following code doesn't write to any file at all ? The first draft of it worked like a charm for a single file... So I wanted to try it on a whole directory. The URLs printed match the real URLs. I have tested one (i.e. manually write the URL in firefox and go to the page) so I know the URL is not the problem...

The winning_lines tuple contains tuples of all possible winning lines -- same numbers as in your version. Then this sequence of tuples is searched to find a match with (player, player, player). In other words, it checks to see that player exist in all three spots in at least one of those winning lines. It performs the exact same logic as your code but is somewhat more efficient since it takes advantage of Python's tuple construction and comparison efficiencies.

For this program it doesn't actually matter, but if you'd been writing an AI to play tic-tac-toe, this function would be called many many times, and the efficiency might make a difference. Also, in my opinion, it is somewhat clearer. But no biggie.

Also, do you know why the following code doesn't write to any file at all ? The first draft of it worked like a charm for a single file... So I wanted to try it on a whole directory. The URLs printed match the real URLs. I have tested one (i.e. manually write the URL in firefox and go to the page) so I know the URL is not the problem...

Don't see anything really wrong off the top. I can only suggest lots and lots of debug prints Also, building strings by concatenation is not the best way to go about things in Python. Use the string formatting operator. For instance, instead of:

I think I have found the problem... It's because the site uses many different naming conventions and uses different prefixes. I will try implementing those naming conventions in my code but right now I'm a bit tired for that.