How to implement client/server (sockets) to two player boggle game - python

Here is the code I currently have. The program works great I just want to make the game playable using sockets. If this game were ran on one computer, I would like two GUI windows to pop up but I am having a tough time doing so. I have used sockets to work with two different computers but I can't seem to implement it the way I want it at the moment.
import tkinter as tk
import random
import socket
import threading
possiblechoices = [["A","E","A","N","E","G"],["A","H","S","P","C","O"],["A","S","P","F","F","K"],["O","B","J","O","A","B"],["I","O","T","M","U","C"],["R","Y","V","D","E","L"],["L","R","E","I","X","D"],["E","I","U","N","E","S"],["W","N","G","E","E","H"],["L","N","H","N","R","Z"],["T","S","T","I","Y","D"],["O","W","T","O","A","T"],["E" ,"R" ,"T" ,"T" ,"Y" ,"L"],["T" ,"O" ,"E" ,"S" ,"S" ,"I"],["T", "E" ,"R" ,"W" ,"H" ,"V"],["N" ,"U" ,"I" ,"H" ,"M" ,"Qu"]]
words = []
with open('words.txt', 'r') as f:
for line in f:
for word in line.split():
newword = word.lower()
words.append(newword)
def new_board():
copy = [i for i in possiblechoices]
columns = []
for i in range(0,4):
columns.append([])
for j in range(0,4):
die = random.choice(copy)
columns[i].append(random.choice(die))
copy.remove(die)
return columns
def adjacent_cells(current_cell):
adj_list = []
x = current_cell[0]
y = current_cell[1]
# get cell above (if y > 0):
if y > 0:
adj_list.append((x, y-1))
# get cell below (if y < 3):
if y < 3:
adj_list.append((x, y+1))
# get left cell (if x > 0):
if x > 0:
adj_list.append((x-1, y))
# get right cell (if x < 3):
if x < 3:
adj_list.append((x+1, y))
# get upper left diagonal (if y > 0 and x > 0):
if y > 0 and x > 0:
adj_list.append((x-1, y-1))
# get upper right diagonal (if y > 0 and x < 3):
if y > 0 and x < 3:
adj_list.append((x+1, y-1))
# get lower left diagonal (if y < 3 and x > 0):
if y < 3 and x > 0:
adj_list.append((x-1, y+1))
# get lower right diagonal (if y < 3 and x < 3):
if y < 3 and x < 3:
adj_list.append((x+1, y+1))
return adj_list
def cells_with_letter(board, letter):
coords = []
for i in range(4):
for j in range(4):
if board[i][j] == letter:
coords.append((j, i))
return coords
def board_has_word(board, word, used_cells = None):
word = word.upper()
if word[0] =='Q' or word[0] =='q':
if used_cells is None:
starting_cells = cells_with_letter(board,"Qu")
if len(starting_cells) == 0:
return False
if len(word) == 2:
return True
else:
for s in starting_cells:
if board_has_word(board, word[2:], [s]):
return True
return False
else:
current_cell = used_cells[-1]
neighbors = adjacent_cells(current_cell)
neighbors = [c for c in neighbors if not c in used_cells]
neighbors = [c for c in neighbors if "Qu" == board[c[1]][c[0]]]
if len(neighbors) == 0:
return False
if len(word) == 2:
return True
else:
for n in neighbors:
if board_has_word(board, word[2:], used_cells + [n]):
return True
return False
if used_cells is None:
starting_cells = cells_with_letter(board, word[0])
if len(starting_cells) == 0:
return False
if len(word) == 1:
return True
else:
for s in starting_cells:
if board_has_word(board, word[1:], [s]):
return True
return False
else:
current_cell = used_cells[-1]
neighbors = adjacent_cells(current_cell)
neighbors = [c for c in neighbors if not c in used_cells]
neighbors = [c for c in neighbors if word[0] == board[c[1]][c[0]]]
if len(neighbors) == 0:
return False
if len(word) == 1:
return True
else:
for n in neighbors:
if board_has_word(board, word[1:], used_cells + [n]):
return True
return False
turn = True
player1score = 0
player2score = 0
usedwords = []
#tk drawing
root = tk.Tk()
frame = tk.Frame(root)
frame.grid(row=0, column=0)
copy = possiblechoices
board = new_board()
for x in range(len(board)):
for y in range(len(board[x])):
letter = board[x][y]
l = tk.Label(frame, text = letter)
l.grid(row = y, column = x)
l1 = tk.Label(root, text="Guess word:")
l1.grid(row=4, column=0)
e1 = tk.Entry(root)
e1.grid(row=4, column=1)
l2 = tk.Label(root, text="You guessed: ")
l2.grid(row=5, column=0)
l3 = tk.Label(root, text="")
l3.grid(row=5, column=1)
#player 1 score
l4 = tk.Label(root, text = "Player 1 Score:")
l4.grid(row = 2,column = 0)
l5 = tk.Label(root, text = (player1score))
l5.grid(row = 2, column = 1)
#payer 2 score
l8 = tk.Label(root, text = "Player 2 Score:")
l8.grid(row = 3, column =0)
l9 = tk.Label(root, text = player2score)
l9.grid(row = 3, column = 1)
#Used words
l6 = tk.Label(root, text = "Used Words")
l6.grid(row = 2, column = 3)
l7 = tk.Label(root, text = usedwords)
l7.grid(row = 3, column = 3)
def make_guess():
global turn
maybe = e1.get().lower()
if(board_has_word(board, maybe)):
if maybe in words:
if maybe not in usedwords:
usedwords.append(maybe)
if(turn):
current = l5["text"]
converted = int(current)
if(not turn):
current = l9["text"]
converted = int(current)
l3.config(text=e1.get().lower())
l7.config(text =usedwords)
if len(maybe) >=3 and len(maybe) <=4:
converted+= 1
if len(maybe) ==5:
converted += 2
if len(maybe) ==6:
converted +=3
if len(maybe) ==7:
converted+=5
if len(maybe) >=8:
converted +=11
if(turn):
l5.config(text = str(converted))
turn = False
elif(not turn):
l9.config(text = str(converted))
turn = True
else:
l3.config(text = "Word already used")
if(turn):
turn = False
elif(not turn):
turn = True
else:
l3.config(text = "Not in dictionary")
else:
l3.config(text = "Word not in board")
def resetgame():
global board
global usedwords
board = new_board()
for x in range(len(board)):
for y in range(len(board[x])):
letter = board[x][y]
l = tk.Label(frame, text = letter)
l.grid(row = y, column = x)
l5.config(text = "0")
l9.config(text = "0")
usedwords = []
l7.config(text = usedwords)
l3.config(text = "")
reset = tk.Button(root, text = 'Reset Game', command = resetgame)
reset.grid(row = 6, column = 5, sticky = tk.W, pady = 4)
b1 = tk.Button(root, text='Submit',command=make_guess)
b1.grid(row=6, column=0, sticky=tk.W, pady=4)
tk.mainloop()

Related

Python Tkinter - Deleting an item from a list when I don't know its index

I'm new to python and I am currently learning for loops in Tkinter and trying to build pin code GUI.
What I want to happen is when the back space button is pressed "<" the last item added to the list "Entered Pin" is removed and 1 Asterix is removed from TxtWindow? I'm wondering if there is a particular way in python to remove the last item added to a list when I am unaware how many items there will be in the list.
Thanks in advance my code is below
import tkinter as tk
window = tk.Tk()
def PinEntry(x):
global u
global counter
if u == 1:
TxtWindow.delete("1.0", "end")
u = u+1
if EntertedPin == DefaultPin:
window.destroy()
if x in range (len(EntryKeyList)):
EntertedPin.append (EntryKeyList [x])
TxtWindow.insert (tk.END, "*")
counter = counter +1
if x == 2:
EntertedPin.clear()
TxtWindow.delete("1.0", "end")
TxtWindow.insert (tk.END, "Enter Pin")
u = 1
coutner = 0
if x == 0:
EntertedPin.clear()
TxtWindow.delete("1.0", "end")
TxtWindow.insert (tk.END, "Enter Pin")
u = 1
counter = 0
if x == 12:
# Delete last number in the list and remove one asterix from the TxtWindow
EntertedPin = []
DefaultPin = [1,2,3,0]
u = 1
counter = -1
TxtWindow = tk.Text(window, relief = "sunken", width = 10, height = 1)
TxtWindow.insert (tk.END, "Enter Pin")
TxtWindow.grid (row = 1, column = 2)
x = 1
y = 1
a = 5
b = 4
c = 1
d = 3
e = 1
f = 2
g = 1
EntryKeyList = ["CLR", 0, "ENT", 1, 2, 3, 4, 5, 6, 7, 8, 9, "<" ]
for i in range (13):
KeypadBtn = tk.Button(window, width = 5, height = 3, text = EntryKeyList[i], command = lambda x=i: PinEntry(x))
if y <=3:
KeypadBtn.grid (row = a , column = x )
x = x +1
y=y +1
elif y <= 6:
KeypadBtn.grid (row = b , column = c )
c = c +1
y=y+1
elif y <= 9:
KeypadBtn.grid (row = d , column = e )
e = e +1
y=y+1
elif y <=12:
KeypadBtn.grid (row = f , column = g )
g = g +1
y=y+1
else:
KeypadBtn.grid (row = 1, column = 3)
window.mainloop()
The commands what you are looking for
TxtWindow.delete("end-2c", "end")
mylist=mylist[:-1] or mylist.pop()
But the code is wrong. The backspace cannot add "x" to widget.
def PinEntry(x):
global u
global counter
global EntertedPin
global DefaultPin
if u == 1:
TxtWindow.delete("1.0", "end")
u = u+1
if x in range (len(EntryKeyList)):
if x == 12:
# Delete last number in the list and remove one asterix from the TxtWindow
EntertedPin=EntertedPin[:-1]
TxtWindow.delete("end-2c", "end")
# If the button is not number:
else:
if x == 2:
EntertedPin.clear()
TxtWindow.delete("1.0", "end")
TxtWindow.insert (tk.END, "Enter Pin")
u = 1
coutner = 0
elif x == 0:
EntertedPin.clear()
TxtWindow.delete("1.0", "end")
TxtWindow.insert (tk.END, "Enter Pin")
u = 1
counter = 0
EntertedPin.append (EntryKeyList [x])
TxtWindow.insert (tk.END, "*")
counter = counter +1
if EntertedPin == DefaultPin:
window.destroy()

While Not Loop running more times than intended

I have a problem where I am trying to make a word search puzzle generator and I have run into multiple problems throughout the day. (Thanks to this community I've solved most of them!)
I have another problem now where I have a loop that should find a spot to place a word, place it, and move on to the next word. Instead it is finding all possible spots the word can be and placing the word in all of them. I only want each word to appear once.
I thought that the lines while not placed and placed = true would handle this but it isn't working.
Thanks in advance for any help, and here is my code:
import tkinter as tk
import random
import string
handle = open('dictionary.txt')
words = handle.readlines()
handle.close()
grid_size = 10
words = [ random.choice(words).upper().strip() \
for _ in range(5) ]
print ("The words are:")
print(words)
grid = [ [ '_' for _ in range(grid_size) ] for _ in range(grid_size) ]
orientations = [ 'leftright', 'updown', 'diagonalup', 'diagonaldown' ]
class Label(tk.Label):
def __init__(self, parent, **kwargs):
super().__init__(parent, **kwargs, font=("Courier", 44))
#self.bind('<Button-1>', self.on_click)
#def on_click(self, event):
#w = event.widget
#row, column = w.grid_info().get('row'), w.grid_info().get('column')
#print('coord:{}'.format((row, column)))
#w.destroy()
class App(tk.Tk):
def __init__(self):
super().__init__()
for row in range(grid_size):
for column in range(grid_size):
for word in words:
word_length = len(word)
placed = False
while not placed:
orientation = random.choice(orientations)
if orientation == 'leftright':
step_x = 1
step_y = 0
if orientation == 'updown':
step_x = 0
step_y = 1
if orientation == 'diagonalup':
step_x = 1
step_y = -1
if orientation == 'diagonaldown':
step_x = 1
step_y = 1
x_position = random.randrange(grid_size)
y_position = random.randrange(grid_size)
ending_x = x_position + word_length*step_x
ending_y = y_position + word_length*step_y
if ending_x < 0 or ending_x >= grid_size: continue
if ending_y < 0 or ending_y >= grid_size: continue
failed = False
for i in range(word_length):
character = word[i]
new_position_x = x_position + i*step_x
new_position_y = y_position + i*step_y
character_at_new_position = grid[new_position_x][new_position_y]
if character_at_new_position != '_':
if character_at_new_position == character:
continue
else:
failed = True
break
if failed:
continue
else:
for i in range(word_length):
character = word[i]
new_position_x = x_position + i*step_x
new_position_y = y_position + i*step_y
grid[new_position_x][new_position_y] = character
if ( grid[row][column] == grid[new_position_x][new_position_y] ):
grid[row][column] = grid[new_position_x][new_position_y]
Label(self, text=character).grid(row=row, column=column)
placed = True
#if ( grid[row][column] == '_' ):
#txt = random.SystemRandom().choice(string.ascii_uppercase)
#Label(self, text=txt).grid(row=row, column=column)
if __name__ == '__main__':
App().mainloop()
I can assure you that your expectation of while loop is correct.
In [1]: placed = False
In [2]: i = 0
In [3]: while not placed:
...: i += 1
...: print(i)
...: if i == 5:
...: placed = True
...:
1
2
3
4
5
Given that, my suspicion is that your code always hit continue, which means it never hits the statement placed = True, hence infinite loop. So I suggest you check if your condition to continue is as expected.
Hope this helps!

Variable input python -Tkinter

I have made a GUI in Tkinter( tennisGUI) which is meant to get "user input" and gives another python scripts(tennisTotal.py) "output.
Everything works except 1 thing I just can't get to work. How to get the "user input" in the other script(tennisTotal.py.
For example, in the GUI there is a field "Service stats Serving player". I want the input from this field into the "tennisTotal.py" script
Any comments and suggestions on the script are also welcome as I'm rather new on pythong.
tennisGUI script
from Tkinter import *
import sys
sys.path.append("C:\Users\Magali\Desktop\Tennis\tennisTotal.py")
class App(Frame):
def run_script(self):
sys.stdout = self
try:
del(sys.modules["tennisTotal"])
except:
# Yeah, it's a real ugly solution...
pass
import tennisTotal
tennisTotal
sys.stdout = sys.__stdout__
def build_widgets(self):
self.text1 = Text(self, height=8, width=25, font=('time', 9, 'italic'))
self.text1.grid(row=13, column=6, columnspan=2, rowspan=50, padx=10, pady=10)
Label(self, text="Players & Stats", font="Verdana 10 bold").grid(row=1, column=2, columnspan=3)
Label(self, text="Serving Player").grid(row=2, column=2, sticky='w')
Label(self, text="Receiving Player").grid(row=3, column=2, sticky='w')
Label(self, text="Scoring", font="Verdana 10 bold").grid(row=13, column=2, columnspan=3)
Label(self, text="Game Score Serving Player").grid(row=14, column=2, sticky='w')
Label(self, text="Game Score Receiving Player").grid(row=15, column=2, sticky='w')
Label(self, text="Set Score Serving Player").grid(row=16, column=2, sticky='w')
Label(self, text="Set Score Receiving Player").grid(row=17, column=2, sticky='w')
Label(self, text="Stats", font="Verdana 10 bold").grid(row=4, column=2, columnspan=3)
Label(self, text="Service stats Serving Player").grid(row=5, column=2, sticky='w')
Label(self, text="Service stats Receiving Player").grid(row=6, column=2, sticky='w')
Label(self, text="Return stats Serving Player").grid(row=7, column=2, sticky='w')
Label(self, text="Return stats Receiving Player").grid(row=8, column=2, sticky='w')
e1 = Entry(self)
e2 = Entry(self)
e3 = Entry(self)
e4 = Entry(self)
e5 = Entry(self)
e6 = Entry(self)
e7 = Entry(self)
e8 = Entry(self)
e9 = Entry(self)
e10 = Entry(self)
e1.insert(10, "Novak Djokovic")
e2.insert(10, "Andy Murray")
e3.insert(10, "30")
e4.insert(10, "15")
e5.insert(10, "2")
e6.insert(10, "1")
e7.insert(10, "75.2%")
e8.insert(10, "72.2%")
e9.insert(10, "30.5%")
e10.insert(10, "27.5%")
e1.grid(row=2, column=4)
e2.grid(row=3, column=4)
e3.grid(row=14, column=4, padx=10)
e4.grid(row=15, column=4)
e5.grid(row=16, column=4)
e6.grid(row=17, column=4)
e7.grid(row=5, column=4)
e8.grid(row=6, column=4)
e9.grid(row=7, column=4)
e10.grid(row=8, column=4)
Button(self, text='Run', command=self.run_script).grid(row=12, column=2, columnspan=6, ipadx=100, pady=15)
def write(self, txt):
self.text1.insert(INSERT, txt)
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.build_widgets()
root = Tk()
app = App(master=root)
app.mainloop()
tennisTotal script --> The first 11 lines is where I want al the "user input" form the tennisGUI script.
s_point=0.6
v_game_point=0
w_game_point=0
v_tiebreak=0
w_tiebreak=0
returnpoint_server=0.3
v_games_in_set=0
w_games_in_set=0
v_sets_won=0
w_sets_won=0
best_of=5
def fact(x):
if x in[0, 1]:
return 1
r = 1
for a in range(1, (x+1)):
r = r*a
return r
def ch(a, b):
return fact(a)/(fact(b)*fact(a-b))
def gameOutcome(s, a, b):
return ch((a+b), a)*(s**a)*((1-s)**b)*s
# Game Probability
def gameProb(s=s_point, v=v_game_point, w=w_game_point):
# function calculates the probability of server winning
# a single game, given p(winning any given point) [s],
# and the current point score.
# v, w = current game score, where love = 0, 15 = 1, etc.
# - e.g. 30-15 is v=2, w=1
# check if game is already over:
if v >= 4 and (v-w) >= 2:
return 1
elif w >= 4 and (w-v) >= 2:
return 0
else:
pass
# if deuce or ad score e.g. 5-4, reduce to e.g. 3-2
while True:
if (v+w) > 6:
v -= 1
w -= 1
else:
break
# specific probabilities:
if w == 0:
w0 = gameOutcome(s, 3-v, 0)
else:
w0 = 0
if w <= 1:
w15 = gameOutcome(s, 3-v, 1-w)
else:
w15 = 0
if w <= 2:
w30 = gameOutcome(s, 3-v, 2-w)
else:
w30 = 0
if v == 4:
wAd, lAd = s, 0
d = 1-s
elif w == 4:
wAd, lAd = 0, 1-s
d = s
else:
wAd, lAd = 0, 0
a = 3 - v
b = 3 - w
d = ch((a+b), a)*(s**a)*((1-s)**b)
if v <= 2:
l30 = gameOutcome((1-s), 3-w, 2-v)
else:
l30 = 0
if v <= 1:
l15 = gameOutcome((1-s), 3-w, 1-v)
else:
l15 = 0
if v == 0:
l0 = gameOutcome((1-s), 3-w, 0)
else:
l0 = 0
# given d = prob of getting to deuce,
# math to divide up further outcomes
denom = s**2 + (1-s)**2
wd = (d*(s**2))/denom
ld = (d*((1-s)**2))/denom
win = w0 + w15 + w30 + wd + wAd
lose = l0 + l15 + l30 + ld + lAd
return win
# Tiebreak Probability
def tiebreakProb(s=s_point, t=returnpoint_server, v=v_tiebreak, w=w_tiebreak, p=7):
# calculate the probability that the current server wins a best-of-p
# tiebreak.
# s = p(server wins service point)
# t = p(current server wins return point)
# v, w = current score
# check if tiebreak is already over:
if v >= p and (v-w) >= 2:
return 1
elif w >= p and (w-v) >= 2:
return 0
else:
pass
# re-adjust so that point score is not higher than p;
# e.g., if p=7 and score is 8-8, adjust to 6-6, which
# is logically equivalent
while True:
if (v+w) > 2*(p-1):
v -= 1
w -= 1
else:
break
outcomes = {}
# track probability of each possible score
# this is messy and probably not optimal, figuring out
# how many points remain, and how many are on each
# player's serve:
for i in range((p-1)):
remain = p + i - v - w
if remain < 1:
continue
else:
pass
if remain % 2 == 1:
if (v+w) % 2 == 0:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain-1)/2
ret = (remain+1)/2
else:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain+1)/2
ret = (remain-1)/2
else:
if (v+w) % 2 == 0:
svc, ret = remain/2, remain/2
else:
svc, ret = (remain-2)/2, (remain-2)/2
if remain % 4 == 0:
svc += 1
ret += 1
else:
svc += 2
# who serves the last point?
if (v+w) % 2 == 0:
if (remain % 4) in [0, 1]:
final = s
svc -= 1
else:
final = t
ret -= 1
else:
if (remain % 4) in [3, 0]:
final = t
ret -= 1
else:
final = s
svc -= 1
pOutcome = 0
for j in range(svc+1):
for k in range(ret+1):
if (j+k) == (p - 1 - v):
m = svc - j
n = ret - k
pr = (s**j)*(t**k)*((1-s)**m)*((1-t)**n)*ch(svc, j)*ch(ret, k)*final
pOutcome += pr
else:
continue
key = str(p) + str(i)
outcomes[key] = pOutcome
if remain % 2 == 1:
if (v+w) % 2 == 0:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain-1)/2
ret = (remain+1)/2
else:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain+1)/2
ret = (remain-1)/2
else:
if (v+w) % 2 == 0:
svc, ret = remain/2, remain/2
else:
svc, ret = (remain-2)/2, (remain-2)/2
if remain % 4 == 0:
svc += 1
ret += 1
else:
svc += 2
# probability of getting to (p-1)-(p-1) (e.g. 6-6)
final = 1
x = 0
for j in range(svc+1):
for k in range(ret+1):
if (j+k) == (p - 1 - v):
m = svc - j
n = ret - k
pr = (s**j)*(t**k)*((1-s)**m)*((1-t)**n)*ch(svc, j)*ch(ret, k)*final
x += pr
else:
continue
outcomes['+'] = (x*s*t)/((s*t) + (1-s)*(1-t))
# add up all positive outcomes
wtb = 0
for z in outcomes:
wtb += outcomes[z]
return wtb
# Set Probability
def setOutcome(final, sGames, rGames, vw, g, h):
pOutcome = 0
for j in range((sGames+1)):
for k in range((rGames+1)):
if (j + k) == (6 - 1 - vw):
m = sGames - j
n = rGames - k
p = (g**j)*(h**k)*((1-g)**m)*((1-h)**n)*ch(sGames, j)*ch(rGames, k)*final
pOutcome += p
else:
continue
return pOutcome
def setGeneral(s=s_point, u=returnpoint_server, v=v_games_in_set, w=w_games_in_set, tb=1):
# calculate the probability of the current server winning
# a 6-game, tiebreak set, given prob. of server winning any
# given service point (s) or return point (u), and the current
# game score (v, w)
# get prob of current server winning a service game:
g = gameProb(s)
# and current server winning a return game:
h = gameProb(u)
# is set over?
if tb:
if v == 7:
return 1
elif w == 7:
return 0
elif v == 6 and (v-w) > 1:
return 1
elif w == 6 and (w-v) > 1:
return 0
else:
pass
else:
if v >= 6 and (v-w) > 1:
return 1
elif w >= 6 and (w-v) > 1:
return 0
else:
pass
# if not over, re-adjust down to no higher than 6-6
while True:
if (v+w) > 12:
v -= 1
w -= 1
else:
break
# if no tiebreak, chance that server wins set is ratio
# of server's prob of winning
# two games in a row to returner's prob of winning two games in a row
if not tb:
deuceprob = (g*h)/((g*h) + (1-g)*(1-h))
outcomes = {}
# special cases, 11 games or more already
if (v+w) == 12:
if tb:
tp = tiebreakProb(s, u)
outcomes['76'] = tp
outcomes['67'] = 1 - tp
else:
outcomes['75'] = deuceprob
outcomes['57'] = 1-deuceprob
elif (v+w) == 11:
if tb:
tp = tiebreakProb((1-u), (1-s))
if v == 6:
outcomes['75'] = g
x = (1-g)
outcomes['76'] = x*(1 - tp)
outcomes['67'] = x*tp
else:
outcomes['57'] = 1-g
x = g
outcomes['76'] = x*(1 - tp)
outcomes['67'] = x*tp
else:
if v == 6:
outcomes['75'] = g
outcomes['57'] = 0
f = 1 - g
else:
outcomes['57'] = 1-g
outcomes['75'] = 0
f = g
outcomes['75'] += f*deuceprob
outcomes['57'] += f*(1-deuceprob)
else:
for i in range(5):
t = 6 + i - v - w
if t < 1:
continue
if t % 2 == 0:
final = h
sGames = t/2
rGames = sGames - 1
else:
final = g
sGames = (t-1)/2
rGames = (t-1)/2
pOutcome = setOutcome(final, sGames, rGames, v, g, h)
key = '6' + str(i)
outcomes[key] = pOutcome
# loss probabilities
# this section isn't necessary, but I wrote it for informal
# testing purposes
for i in range(5):
t = 6 + i - v - w
if t < 1:
continue
if t % 2 == 0:
final = 1-h
sGames = t/2
rGames = sGames - 1
else:
final = 1-g
sGames = (t-1)/2
rGames = (t-1)/2
pOutcome = setOutcome(final, sGames, rGames, w, (1-g), (1-h))
key = str(i) + '6'
outcomes[key] = pOutcome
t = 10 - v - w
if t % 2 == 0:
sGames = t/2
rGames = t/2
else:
sGames = (t-1)/2 + 1
rGames = (t-1)/2
f = setOutcome(1, sGames, rGames, v, g, h)
if tb == 1:
outcomes['75'] = f*g*h
outcomes['57'] = f*(1-g)*(1-h)
x = f*g*(1-h) + f*(1-g)*h
if (v+w) % 2 == 0:
tp = tiebreakProb(s, u)
else:
tp = tiebreakProb(u, s)
outcomes['76'] = x*tp
outcomes['67'] = x - x*tp
else:
outcomes['75'] = f*deuceprob
outcomes['57'] = f*(1-deuceprob)
win = 0
for o in outcomes:
if o in ['60', '61', '62', '63', '64', '75', '76']:
win += outcomes[o]
else:
pass
return win
#Match Probability
def matchGeneral(e, v=0, w=0, s=3):
# calculates probability of winning the match
# from the beginning of a set
# e is p(winning a set)
# v and w is current set score
# s is total number of sets ("best of")
towin = (s+1)/2
left = towin - v
if left == 0:
return 1
remain = s - v - w
if left > remain:
return 0
win = 0
for i in range(left, (remain+1)):
add = ch((i-1), (left-1))*(e**(left-1))*((1-e)**(i-left))*e
win += add
return win
def matchProb(s=s_point, t=returnpoint_server, gv=v_game_point, gw=w_game_point, sv=v_games_in_set, sw=w_games_in_set, mv=v_sets_won, mw=w_sets_won, sets=best_of):
# calculates probability of winning a match from any given score,
# given:
# s, t: p(server wins a service point), p(server wins return point)
# gv, gw: current score within the game. e.g. 30-15 is 2, 1
# sv, sw: current score within the set. e.g. 5, 4
# mv, mw: current score within the match (number of sets for each player)
# v's are serving player; w's are returning player
# sets: "best of", so default is best of 3
a = gameProb(s)
b = gameProb(t)
c = setGeneral(s, t)
if gv == 0 and gw == 0:
if sv == 0 and sw == 0:
return matchGeneral(c, v=mv, w=mw, s=sets)
else:
sWin = setGeneral(a, b, s, t, v=sv, w=sw)
sLoss = 1 - sWin
elif sv == 6 and sw == 6:
sWin = tiebreakProb(s, t, v=gv, w=gw)
sLoss = 1 - sWin
else:
gWin = gameProb(s, v=gv, w=gw)
gLoss = 1 - gWin
sWin = gWin*(1 - setGeneral((1-b), (1-a), (1-t), (1-s), v=sw, w=(sv+1)))
sWin += gLoss*(1 - setGeneral((1-b), (1-a), (1-t), (1-s), v=(sw+1), w=sv))
sLoss = 1 - sWin
mWin = sWin*matchGeneral(c, v=(mv+1), w=mw, s=sets)
mWin += sLoss*matchGeneral(c, v=mv, w=(mw+1), s=sets)
return mWin, sLoss
print "Server Game = ""{0:.2%}".format(gameProb())
print "Receiver Game = ""{0:.2%}".format(1-gameProb())
print "Server Tiebreak = ""{0:.2%}".format(tiebreakProb())
print "Receiver Tiebreak = ""{0:.2%}".format(1-tiebreakProb())
print "Server Set = ""{0:.2%}".format(setGeneral())
print "Receiver Set = ""{0:.2%}".format(1-setGeneral())
print "Server Match = ""{0:.2%}".format(matchProb())
print "Receiver Match= ""{0:.2%}".format(1-matchProb())

Attribute error: Object has no attribute Python

I am trying to program a version of conway's game of life however I keep getting the message 'Cell' Object Has no attribute 'nextState' when it seems like it should declare the value of nextState before asking to reference it. here is my code:
from tkinter import *
root = Tk()
class Cell (Button):
Dead = 0
Live = 1
def __init__ (self,parent):
Button.__init__(self,parent, relief = "raised" , width = 2 , borderwidth = 1 , command = self.onpress)
self.displayState(Cell.Dead)
def onpress (self):
if self.state == Cell.Live:
self.displayState(Cell.Dead)
elif self.state == Cell.Dead:
self.displayState(Cell.Live)
def setNextState (self , Neighbours):
if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
self.nextState = Cell.Dead
elif self.state == Cell.Dead and Neighbours == 3:
self.nextState = Cell.Live
elif self.state == Cell.Dead and Neighbours != 3:
self.nextState = self.state
def stepToNextState(self):
self.displayState(self.nextState)
def displayState (self , newstate):
self.state = newstate
if self.state == Cell.Live:
self["bg"] = "black"
if self.state == Cell.Dead:
self["bg"] = "white"
class Grid:
def __init__(self,parent,sizex,sizey):
self.sizex = sizex
self.sizey = sizey
self.cells = []
for a in range (0,self.sizex):
rowcells = []
for b in range (0, self.sizey):
c = Cell(parent)
c.grid(row=b , column=a)
rowcells.append(c)
self.cells.append(rowcells)
def step (self):
cells = self.cells
for x in range (0,self.sizex):
if x==0: x_down = self.sizex-1
else: x_down = x-1
if x==self.sizex-1: x_up = 0
else: x_up = x+1
for y in range(0,self.sizey):
if y==0: y_down = self.sizey-1
else: Y_down = y-1
if y==self.sizey-1: y_up = 0
else: y_up = y+1
sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
cells[x][y].setNextState(sum)
for row in cells:
for cell in row:
cell.stepToNextState()
def clear(self):
for row in self.cells:
for cell in row:
cell.displayState(Cell.Dead)
if __name__ == "__main__":
frame = Frame(root)
frame.pack()
grid = Grid(frame,25,25)
bottomFrame = Frame(root)
bottomFrame.pack (side = BOTTOM)
buttonStep = Button(bottomFrame , text="Step" , command=grid.step)
buttonStep.pack(side = LEFT)
buttonClear = Button(bottomFrame, text = "Clear", command=grid.clear)
buttonClear.pack(side=LEFT , after=buttonStep)
root.mainloop()
The error message is:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 65, in step
cell.stepToNextState()
File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 27, in stepToNextState
self.displayState(self.nextState)
AttributeError: 'Cell' object has no attribute 'nextState'
If anyone could point out where the error is occuring / what is causing it and possibly a way to fix it I would be very grateful.
The issue appears to be that your for row in cells loop is inside of your previous for x in range(0, self.sizex) loop. Here's what the step method should look like if you get it correctly indented:
def step (self):
cells = self.cells
for x in range (0,self.sizex):
if x==0: x_down = self.sizex-1
else: x_down = x-1
if x==self.sizex-1: x_up = 0
else: x_up = x+1
for y in range(0,self.sizey):
if y==0: y_down = self.sizey-1
else: Y_down = y-1
if y==self.sizey-1: y_up = 0
else: y_up = y+1
sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
cells[x][y].setNextState(sum)
for row in cells: # unindent these
for cell in row: # lines by one
cell.stepToNextState() # level each
If all the indentation issues are taken care of (or were not in the original code), there's still an issue that may cause an issue in certain situations. The issue is that the Cell.setNextState method doesn't handle every situation. Specifically, it doesn't set nextState if a cell is alive and should stay so (it has two or three living neighbors). The lack of an else on your chain of if and elif statements should have raised this as a red flag for me, but I overlooked it the first time I examined the function.
Here's how it can be fixed:
def setNextState (self , Neighbours):
if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
self.nextState = Cell.Dead
elif self.state == Cell.Dead and Neighbours == 3:
self.nextState = Cell.Live
else: # remove the conditions on this block, all the state changes were handled above
self.nextState = self.state

how to solve the print string error on python eclipse

I am not sure why do i get this error from the console:
<<
print stirngp[state[i][j]]
^
SyntaxError: invalid syntax
<<
Furthermore it seems that the IDE put a red close on the following code line
line = raw_input("Enter:")
I am not sure what did i do wrong, the following code is as shown below
def isTerminal(state):
stateT = zip(*state)
for i in range(3):
if all(state[i][0] == j for j in state[i]) and state[i][0] != 0:
return state[i][0]
if all(stateT[i][0] == j for j in stateT[i]) and stateT[i][0] != 0:
return stateT[i][0]
if (state[0][0] == state[1][1] == state[2][2]) or \
(state[0][2] == state[1][1] == state[2][0]):
if state[1][1] != 0:
return state[1][1]
for i in range(3):
if 0 in state[i]:
return None
return 0
def succ(state):
# print state
countX = 0
countO = 0
for i in range(3):
for j in range(3):
if state[i][j] == 1: countX = countX + 1
if state[i][j] == -1: countO = countO + 1
if countX > countO:
player = "MIN"
else:
player = "MAX"
succList = []
v = {"MIN":-1,"MAX":1}
for i in range(3):
for j in range(3):
if state[i][j] == 0:
succ = [k[:] for k in state]
succ[i][j] = v[player]
succList = succList + [succ]
# print succList
return succList
def nextplay(player):
if player == "MIN":
return "MAX"
else:
return "MIN"
def minimax(state,alpha,beta,player):
value = isTerminal(state)
if value != None:
# print "TERMINAL:", state, value, player
return value
if player == "MIN":
for y in succ(state):
beta = min(beta, minimax(y,alpha,beta,"MAX"))
if beta <= alpha: return alpha
return beta
if player == "MAX":
for y in succ(state):
alpha = max(alpha, minimax(y,alpha,beta,"MIN"))
if alpha >= beta: return beta
return alpha
def printing(state):
p = {-1:"O",0:".",1:"X"}
for i in range(3):
for j in range(3):
print p[state[i][j]],
print ""
print ""
def main():
state = [[0,0,0],
[0,0,0],
[0,0,0]]
val = isTerminal(state)
while val == None:
line = raw_input("Enter:")
x = line.split(",")
a = int(x[0]); b = int(x[1])
state[a][b] = 1
if isTerminal(state) != None:
printing(state)
return
# determine which successive state is better
succList = succ(state)
succValList = []
for i in succList:
succValList = succValList + [(minimax(i,-1,1,"MAX"),i)]
succValList.sort(key=lambda x:x[0])
state = succValList[0][1] # can also randomly choose other states of the same minimax value
printing(state)
val = isTerminal(state)
if __name__ == '__main__':
main()
As far as i know you can't use raw_input() in Python 3. It's been changed to just input()
http://docs.python.org/dev/whatsnew/3.0.html
also what is stringp? is it an existing list?
if so then state[i][j] MUST return an integer so you can retrieve the item at that index of stringp[]

Categories

Resources