tictactoe script - commented - may have pedagogical value

2017-09-04 Thread namenobodywants

"""
this program makes an optimal tictactoe move by answering the following 
questions 
in their given order until it is told where to put its mark:

1) can you win the game? 
if so then do it
2) could your opponent win the game if it was his turn? 
if so then put your own mark where a mark of his would win him the game
3) could you win the game if you had two turns in a row?
if so then make a move that leaves you with the largest number of second 
moves 
that would win you the game if you could really make them
4) is the center square open?
if so then put your mark there
5) are any of the corners open?
if so then put your mark on one of them
6) put your mark on any open square
"""

#) tictactoe; python 3.6.1

count = lambda dictionary, value: list(dictionary.values()).count(value)
subdictionary = lambda dictionary, keys: {key: dictionary[key] for key in keys}

ex, oh, blank = 'X0 '

indices = list(range(3))
vectors = [(i,j) for i in indices for j in indices]
startgrid = {vector: blank for vector in vectors}

display = lambda grid: '\n-+-+-\n'.join('|'.join(grid[i,j] for j in indices) 
for i in indices) 

iscenter = lambda vector: vector == (1,1)
iscorner = lambda vector: vector[0]%2 == vector[1]%2 == 0

horizontal = [[(i,j) for j in indices] for i in indices]
vertical   = [[(i,j) for i in indices] for j in indices]
diagonal   = [[(i,i) for i in indices], [(i,2-i) for i in indices]]
linear = horizontal + vertical + diagonal
getrows= lambda grid: [subdictionary(grid,coordlist) for coordlist in 
linear]

movermark = lambda grid: ex if count(grid,ex) == count(grid,oh) else oh
opponent  = lambda mark: ex if mark == oh else oh if mark == ex else blank

strike   = lambda vector, rows, ownmark: int(any(row for row in rows if vector 
in row and count(row,blank)==1 and count(row,ownmark)==2))
parry= lambda vector, rows, ownmark: int(any(row for row in rows if vector 
in row and count(row,blank)==1 and count(row,opponent(ownmark))==2))
threaten = lambda vector, rows, ownmark: len([row for row in rows if vector in 
row and count(row,blank)==2 and count(row,ownmark)==1])
position = lambda vector, rows, ownmark: 2 * int(iscenter(vector)) + 
int(iscorner(vector))
evaluate = lambda vector, rows, ownmark: [f(vector,rows,ownmark) for f in 
(strike,parry,threaten,position)]

def movevector(grid,ownmark):
from random import choice
rows = getrows(grid)
value = lambda vector: evaluate(vector,rows,ownmark)
candidates = [(i,j) for i in indices for j in indices if grid[i,j] == blank]
maximum = value(max(candidates,key=value)) if candidates else None
coords = [vector for vector in candidates if value(vector) == maximum]
return choice(coords) if coords and blank in grid.values() else None

def getwinner(grid):
rows = getrows(grid)
rows = [list(row.values()) for row in rows]
return ex if [ex]*3 in rows else oh if [oh]*3 in rows else None

def makemove(grid):
grid = grid.copy()
ownmark = movermark(grid)
vector = movevector(grid,ownmark)
if vector: grid[vector] = ownmark
return grid

def getinteger(lower,upper,prompt):
integer = None
while integer == None:
try:
integer = int(input(prompt))
assert lower <= integer <= upper
except KeyboardInterrupt: raise
except: pass
return integer

def play(mark):
grid = startgrid.copy()
if mark == ex: grid = makemove(grid)
print('\n\n' + display(grid) + '\n\n')
winner = None
while not winner and blank in grid.values():
cellnumber = getinteger(1,9,'cell number: ')
grid[divmod(cellnumber-1,3)] = movermark(grid)
winner = getwinner(grid)
if not winner: grid = makemove(grid) 
winner = getwinner(grid)
print('\n\n' + display(grid) + '\n\n')
message = winner + ' wins' if winner else 'tied game'
print(message)
















-- 
https://mail.python.org/mailman/listinfo/python-list


seeking advice about strategic-game ai

2017-09-05 Thread namenobodywants
i plan to try writing an ai for a strategic game, and i've pretty much narrowed 
the candidates down to either checkers or 

reversi. i would prefer to tackle the easier game, so can anybody tell me which 
one is easier to program decently? (or maybe 

i'm missing a good candidate - basically all i want is a game that's less 
trivial than tictactoe). by "decently" i mean that it 

should make reasonably skillful moves in a reasonable amount of time, but speed 
and playing strength take a backseat to the 

simplicity and well-motivatedness of the algorithm. (this isn't supposed to be 
a professional-caliber ai ... it will be more like a 

kid's science-fair project). 

more particularly, can anybody give me some high-level guidance about 
evaluation functions for either game? (no spoilers 

please - i want this to be really my own project). as far as reversi goes, my 
ideas on this matter are based mostly on the 

"basic diagram" in goro hasegawa's "how to win at othello". (i have a library 
hold on norvig's "paradigms of ai programming", 

which devotes an entire chapter to reversi, but the book hasn't come in yet). 
as for checkers, i was thinking about a weighted 

sum of three basic measurements ... if "you" and "i" are the players, then i 
would measure

*) (my relative mobility)  = (the number of moves i have) - (the number 
of moves you have)
*) (my relative king presence)  = (the number of kings i have)  - (the number 
of kings you have)
*) (my relative pawn presence) = (the number of pawns i have) - (the number of 
pawns you have)

indeed, i've even wondered whether a viable evaluation could be based on 
relative mobility alone - that would, after all, work 

perfectly if there were no limit to the search horizon - but on the other hand 
i'm also prepared to find out that any viable 

evaluation needs to be more sophisticated. i wouldn't be surprised, for 
example, if the approach i'm suggesting could work 

but only if the weights in the sum are adjusted according to the number of 
moves made or some other criterion. 

anyway, that should suffice to give you an idea of where i'm at with this. 
thanks if you can help

peace
stm 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: tictactoe script - commented - may have pedagogical value

2017-09-05 Thread namenobodywants
good point. this algorithm doesn't take account of the fact that one can make a 
threat (x's 147) by parrying a threat (o's 357). nevertheless i'm still certain 
that the components the algorithm is built from are the same components i use 
myself to play tictactoe, and i'm still certain that my own tictactoe playing 
is optimal. that's my motivation for doing it this way: i'm trying to formalize 
the algorithm i use myself. besides, exhaustive minimax search seems like 
cheating to me, since it doesn't generalize to less-trivial games. anyway, 
thanks for pointing out the error

peace
stm
-- 
https://mail.python.org/mailman/listinfo/python-list


connect four (game)

2017-11-24 Thread namenobodywants
hi all

i've just finished my first excursion into artificial intelligence with a game 
less trivial than tictactoe, and here it is in case anybody can offer 
criticism/suggestions/etc

peace
stm


###
#) connectfour - python 3.6.1
###

from tkinter import *
from random  import choice

class infinity:
def __init__(self,signum): self.signum = signum
def __repr__(self): return '+oo' if self.signum > 0 else '-oo'
def __lt__(self,other): return False if self.signum > 0 else True
def __le__(self,other): return False if self.signum > 0 else True
def __gt__(self,other): return True  if self.signum > 0 else False
def __ge__(self,other): return True  if self.signum > 0 else False
def __eq__(self,other): return isinstance(other,infinity) and self.signum 
== other.signum

ex, oh, blank = 'red black white' .split()

startboard = {(i,j):blank for i in range(6) for j in range(7)}

def getlines(board):
horizontal = [[(i,   j+k) for k in range(4)] for i in range(6) for j in 
range(7)]
vertical   = [[(i+k, j)   for k in range(4)] for i in range(6) for j in 
range(7)]
positive   = [[(i+k, j+k) for k in range(4)] for i in range(6) for j in 
range(7)]
negative   = [[(i+k, j-k) for k in range(4)] for i in range(6) for j in 
range(7)]
linear = horizontal + vertical + positive + negative
lines  = [line for line in linear if all(i in range(6) and j in 
range(7) for (i,j) in line)]
return [[board[square] for square in line] for line in lines]

def getwinner(board):
lines = getlines(board)
return ex if [ex]*4 in lines else oh if [oh]*4 in lines else None

def getmover(board):
boardvalues = list(board.values())
return ex if boardvalues.count(ex)==boardvalues.count(oh) else oh

def getoptimum(mover):
return max if mover == ex else min

def getaccessibles(board):
return [j for j in range(7) if board[0,j] == blank]

def getvalue(winner,accessibles):
return infinity(+1) if winner == ex else infinity(-1) if winner == oh else 
0 if not accessibles else None

def makemove(board,column,mover):
board = board.copy()
empties = [row for row in range(6) if board[row,column] == blank]
if not empties: return board
board[max(empties),column] = mover
return board

def takemoveback(board,column):
board = board.copy()
occupied = [row for row in range(6) if board[row,column] != blank]
if not occupied: return board
board[min(occupied),column] = blank
return board

def guessvalue(board):
lines = getlines(board)
exs = [line for line in lines if line.count(ex)==3 and line.count(oh)==0] 
ohs = [line for line in lines if line.count(oh)==3 and line.count(ex)==0] 
return len(exs)-len(ohs)

def heuristicvalue(board,depth):
winner  = getwinner(board)
accessibles = getaccessibles(board)
value   = getvalue(winner,accessibles)
if value != None: return value
if depth == 0:return guessvalue(board)
mover= getmover(board)
optimum  = getoptimum(mover)
children = [makemove(board,column,mover) for column in accessibles]
return optimum(heuristicvalue(child,depth-1) for child in children)

def getmoves(board,depth): 
accessibles = getaccessibles(board)
if not accessibles: return []
mover = getmover(board)
optimum   = getoptimum(mover)
children  = [makemove(board,column,mover) for column in accessibles]
values= [heuristicvalue(child,depth)  for child  in children]
bestvalue = optimum(values)
return [accessibles[index] for index in range(len(accessibles)) if 
values[index] == bestvalue]

class grid:
def __init__(self,window):
self.window= window
self.boardframe= Frame(window.root)
self.rowframes = [Frame(self.boardframe) for anonymous in range(6)]
self.squarebuttons = [Button(self.rowframes[number//7], width=3, 
command=self.window.squarecommand(number), background=blank) for number in 
range(42)]
def pack(self):
self.boardframe .pack(side=TOP)
[frame  .pack(side=TOP)  for frame  in self.rowframes]  
[button .pack(side=LEFT) for button in self.squarebuttons]

class caption:
def __init__(self,window):
self.window  = window
self.statusframe = Frame(window.root)
self.statuslabel = Label(self.statusframe, height=2)
def pack(self):
self.statusframe .pack(side=TOP)
self.statuslabel .pack(side=LEFT)

class buttonpanel:
def __init__(self,window,depth):
self.window  = window
self.controlframe= Frame(window.root)
self.makemoveframe   = Frame(self.controlframe)
self.takebackframe   = Frame(self.controlframe)
self.startoverframe  = Frame(self.controlframe)
self.makemovebutton  = Button(self.makemoveframe,  text='make move',  
command=self.window.move

Re: connect four (game)

2017-11-24 Thread namenobodywants
On Friday, November 24, 2017 at 12:13:18 PM UTC-8, Terry Reedy wrote:

> Since you did not start with tests or write tests as you wrote code, ...

why on earth would you assume that? instantiate "window" and you'll see it 
works exactly as i intended; nobody's asking you to debug code for free; i'm 
looking for the kind of feedback the other respondent gave

peace
stm


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-25 Thread namenobodywants
On Saturday, November 25, 2017 at 5:00:12 AM UTC-8, bartc wrote:

> Actually I've no idea what these tests are supposed to prove. 

me neither; i think you guys may be getting me out of my depth now


> They are to do with one class called 'infinity', which is never used in the 
> rest 
> of the program apart from one line.
> 
> I established that within a few seconds, and I would concentrate on what 
> 'infinity' is actually for, rather than go to considerable lengths to 
> test a class that may not actually be needed.

my current version of "infinity" looks like this

class Infinity:
def __init__(self,signum): self.signum = (+1) if signum > 0 else (-1)
def __repr__(self): return '+oo' if self.signum == (+1) else '-oo'
def __lt__(self,other): return self.signum == (-1)
def __le__(self,other): return self.signum == (-1)
def __gt__(self,other): return self.signum == (+1)
def __ge__(self,other): return self.signum == (+1)
def __eq__(self,other): return isinstance(other,Infinity) and self.signum 
== other.signum

the idea is that there should be exactly one object posinf (positive infinity) 
that compares as strictly greater than any number ever considered, and exactly 
one object neginf that compares as strictly less; as the code stands now there 
is no reason not to use +/-70 in that capacity; the "infinity" class is there 
so that the game-playing parts of the code (which at present are intentionally 
as primitive as possible) can be modified more smoothly later; the single place 
where "infinity" is instantiated is in the function "getvalue", which returns 
the value of a finished game:

def getvalue(winner,accessibles):
return Infinity(+1) if winner == ex else Infinity(-1) if winner == oh else 
0 if not accessibles else None

if ex has won then the value of the game is posinf; if oh has won then it's 
neginf; if the game is tied (no winner but no accessible columns remaining) 
then the value of the game is zero; otherwise the game is not finished and its 
finished value is None

peace
stm







-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-25 Thread namenobodywants
On Friday, November 24, 2017 at 8:07:07 AM UTC-8, Chris Angelico wrote:

> This is the kind of function that needs a docstring and some comments.
> What exactly is this doing? What are the "lines" of the board? What's
> the difference between "linear" and "lines"? What exactly is it
> returning?

producing documentation is an extremely difficult task for me, but i've come up 
with the following:

"""
makelines(length,numrows,numcolumns) IS THE LIST OF ALL LISTS L, WITH LENGTH 
length, OF COORDINATES
FROM A numrows x numcolumns MATRIX, SUCH THAT THE ENTRIES OF L ALL LIE IN A 
LINE:

LET horizontal BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A 
HORIZONTAL LINE
LET vertical BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A 
VERTICAL LINE
LET downward BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A 
DOWNWARD-SLOPING DIAGONAL LINE
LET upward BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN AN 
UPWARD-SLOPING DIAGONAL LINE
THEN makelines(length,numrows,numcolumns) IS THE UNION OF ALL THE 
AFOREMENTIONED SETS
"""

def makelines(length,numrows,numcolumns): 
horizontal = [[(i, j+k) for k in range(length)] for i in range(numrows) for 
j in range(numcolumns)] 
vertical = [[(i+k, j) for k in range(length)] for i in range(numrows) for j 
in range(numcolumns)] 
downward = [[(i+k, j+k) for k in range(length)] for i in range(numrows) for 
j in range(numcolumns)] 
upward = [[(i+k, j-k) for k in range(length)] for i in range(numrows) for j 
in range(numcolumns)] 
linear = horizontal + vertical + downward + upward 
return [line for line in linear if all(i in range(6) and j in range(7) for 
(i,j) in line)]

def getlines(board):
coordlines = makelines(4,6,7) ## GLOBAL
return [[board[square] for square in line] for line in coordlines


i tried to remove all the superfluous spaces from that, but lining up code 
vertically is very helpful to me, so i don't think i can really dispense with 
the practice

peace
stm
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-25 Thread namenobodywants
On Saturday, November 25, 2017 at 12:48:38 AM UTC-8, Terry Reedy wrote:

> I did, and it looks buggy to me.  The top and left frame lines are 
> missing.  If I click a square, the bottom square in the column lights 
> up.  But then I have no idea whether those are your intentions or not.

i hadn't noticed about the frame lines, but it's the same for me; but i'm 
hoping you meant to write that the TOP square in a column flashes when you 
"drop a token" down that column; if you really meant the bottom one then i'm 
totally baffled that it could be the top one for me and the bottom one for you 
... is that something that can happen because of a bug? 

sorry if you were offended by what i wrote before; i didn't understand what you 
meant

peace
stm
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-26 Thread namenobodywants
On Friday, November 24, 2017 at 8:07:07 AM UTC-8, Chris Angelico wrote:

> This is the kind of function that needs a docstring and some comments.
> What exactly is this doing? What are the "lines" of the board? What's
> the difference between "linear" and "lines"? What exactly is it
> returning?

producing documentation is an extremely difficult task for me, but i've come up
 with the following:

"""
makelines(length,numrows,numcolumns) IS THE LIST OF ALL LISTS L, WITH LENGTH
length, OF COORDINATES
FROM A numrows x numcolumns MATRIX, SUCH THAT THE ENTRIES OF L ALL LIE IN A
LINE:

LET horizontal BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A
HORIZONTAL LINE
LET vertical BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A
VERTICAL LINE
LET downward BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A
DOWNWARD-SLOPING DIAGONAL LINE
LET upward BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN AN
UPWARD-SLOPING DIAGONAL LINE
THEN makelines(length,numrows,numcolumns) IS THE UNION OF ALL THE
AFOREMENTIONED SETS
"""

def makelines(length,numrows,numcolumns):
horizontal = [[(i, j+k) for k in range(length)] for i in range(numrows) for
j in range(numcolumns)]
vertical = [[(i+k, j) for k in range(length)] for i in range(numrows) for j
in range(numcolumns)]
downward = [[(i+k, j+k) for k in range(length)] for i in range(numrows) for
j in range(numcolumns)]
upward = [[(i+k, j-k) for k in range(length)] for i in range(numrows) for j
in range(numcolumns)]
linear = horizontal + vertical + downward + upward
return [line for line in linear if all(i in range(6) and j in range(7) for
(i,j) in line)]

def getlines(board):
coordlines = makelines(4,6,7) ## GLOBAL
return [[board[square] for square in line] for line in coordlines


i tried to remove all the superfluous spaces from that, but lining up code
vertically is very helpful to me, so i don't think i can really dispense with
the practice

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-26 Thread namenobodywants
On Saturday, November 25, 2017 at 5:00:12 AM UTC-8, bartc wrote:

> Actually I've no idea what these tests are supposed to prove.

me neither; i think you guys may be getting me out of my depth now


> They are to do with one class called 'infinity', which is never used in the
rest
> of the program apart from one line.
>
> I established that within a few seconds, and I would concentrate on what
> 'infinity' is actually for, rather than go to considerable lengths to
> test a class that may not actually be needed.

my current version of "infinity" looks like this

class Infinity:
def __init__(self,signum): self.signum = (+1) if signum > 0 else (-1)
def __repr__(self): return '+oo' if self.signum == (+1) else '-oo'
def __lt__(self,other): return self.signum == (-1)
def __le__(self,other): return self.signum == (-1)
def __gt__(self,other): return self.signum == (+1)
def __ge__(self,other): return self.signum == (+1)
def __eq__(self,other): return isinstance(other,Infinity) and self.signum
== other.signum

the idea is that there should be exactly one object posinf (positive infinity)
that compares as strictly greater than any number ever considered, and exactly
one object neginf that compares as strictly less; as the code stands now there
is no reason not to use +/-70 in that capacity; the "infinity" class is there
so that the game-playing parts of the code (which at present are intentionally
as primitive as possible) can be modified more smoothly later; the single place
 where "infinity" is instantiated is in the function "getvalue", which returns
the value of a finished game:

def getvalue(winner,accessibles):
return Infinity(+1) if winner == ex else Infinity(-1) if winner == oh else
0 if not accessibles else None

if ex has won then the value of the game is posinf; if oh has won then it's
neginf; if the game is tied (no winner but no accessible columns remaining)
then the value of the game is zero; otherwise the game is not finished and its
finished value is None

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-26 Thread namenobodywants
On Saturday, November 25, 2017 at 12:48:38 AM UTC-8, Terry Reedy wrote:

> I did, and it looks buggy to me.  The top and left frame lines are
> missing.  If I click a square, the bottom square in the column lights
> up.  But then I have no idea whether those are your intentions or not.

i hadn't noticed about the frame lines, but it's the same for me; but i'm
hoping you meant to write that the TOP square in a column flashes when you
"drop a token" down that column; if you really meant the bottom one then i'm
totally baffled that it could be the top one for me and the bottom one for you
... is that something that can happen because of a bug?

sorry if you were offended by what i wrote before; i didn't understand what you
 meant

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-26 Thread namenobodywants
On Saturday, November 25, 2017 at 5:00:12 AM UTC-8, bartc wrote:

> Actually I've no idea what these tests are supposed to prove.

me neither; i think you guys may be getting me out of my depth now


> They are to do with one class called 'infinity', which is never used in the
rest
> of the program apart from one line.
>
> I established that within a few seconds, and I would concentrate on what
> 'infinity' is actually for, rather than go to considerable lengths to
> test a class that may not actually be needed.

my current version of "infinity" looks like this

class Infinity:
def __init__(self,signum): self.signum = (+1) if signum > 0 else (-1)
def __repr__(self): return '+oo' if self.signum == (+1) else '-oo'
def __lt__(self,other): return self.signum == (-1)
def __le__(self,other): return self.signum == (-1)
def __gt__(self,other): return self.signum == (+1)
def __ge__(self,other): return self.signum == (+1)
def __eq__(self,other): return isinstance(other,Infinity) and self.signum
== other.signum

the idea is that there should be exactly one object posinf (positive infinity)
that compares as strictly greater than any number ever considered, and exactly
one object neginf that compares as strictly less; as the code stands now there
is no reason not to use +/-70 in that capacity; the "infinity" class is there
so that the game-playing parts of the code (which at present are intentionally
as primitive as possible) can be modified more smoothly later; the single place
 where "infinity" is instantiated is in the function "getvalue", which returns
the value of a finished game:

def getvalue(winner,accessibles):
return Infinity(+1) if winner == ex else Infinity(-1) if winner == oh else
0 if not accessibles else None

if ex has won then the value of the game is posinf; if oh has won then it's
neginf; if the game is tied (no winner but no accessible columns remaining)
then the value of the game is zero; otherwise the game is not finished and its
finished value is None

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-26 Thread namenobodywants
On Friday, November 24, 2017 at 8:07:07 AM UTC-8, Chris Angelico wrote:

> This is the kind of function that needs a docstring and some comments.
> What exactly is this doing? What are the "lines" of the board? What's
> the difference between "linear" and "lines"? What exactly is it
> returning?

producing documentation is an extremely difficult task for me, but i've come up
 with the following:

"""
makelines(length,numrows,numcolumns) IS THE LIST OF ALL LISTS L, WITH LENGTH
length, OF COORDINATES
FROM A numrows x numcolumns MATRIX, SUCH THAT THE ENTRIES OF L ALL LIE IN A
LINE:

LET horizontal BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A
HORIZONTAL LINE
LET vertical BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A
VERTICAL LINE
LET downward BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN A
DOWNWARD-SLOPING DIAGONAL LINE
LET upward BE ALL THE APPROPRIATE-LENGTH LISTS WHOSE ENTRIES LIE IN AN
UPWARD-SLOPING DIAGONAL LINE
THEN makelines(length,numrows,numcolumns) IS THE UNION OF ALL THE
AFOREMENTIONED SETS
"""

def makelines(length,numrows,numcolumns):
horizontal = [[(i, j+k) for k in range(length)] for i in range(numrows) for
j in range(numcolumns)]
vertical = [[(i+k, j) for k in range(length)] for i in range(numrows) for j
in range(numcolumns)]
downward = [[(i+k, j+k) for k in range(length)] for i in range(numrows) for
j in range(numcolumns)]
upward = [[(i+k, j-k) for k in range(length)] for i in range(numrows) for j
in range(numcolumns)]
linear = horizontal + vertical + downward + upward
return [line for line in linear if all(i in range(6) and j in range(7) for
(i,j) in line)]

def getlines(board):
coordlines = makelines(4,6,7) ## GLOBAL
return [[board[square] for square in line] for line in coordlines


i tried to remove all the superfluous spaces from that, but lining up code
vertically is very helpful to me, so i don't think i can really dispense with
the practice

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-26 Thread namenobodywants
On Saturday, November 25, 2017 at 12:48:38 AM UTC-8, Terry Reedy wrote:

> I did, and it looks buggy to me.  The top and left frame lines are
> missing.  If I click a square, the bottom square in the column lights
> up.  But then I have no idea whether those are your intentions or not.

i hadn't noticed about the frame lines, but it's the same for me; but i'm
hoping you meant to write that the TOP square in a column flashes when you
"drop a token" down that column; if you really meant the bottom one then i'm
totally baffled that it could be the top one for me and the bottom one for you
... is that something that can happen because of a bug?

sorry if you were offended by what i wrote before; i didn't understand what you
 meant

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-27 Thread namenobodywants
On Sunday, November 26, 2017 at 7:09:25 PM UTC-8, Michael Torrie wrote:
 
> So you are using this Infinity class as a sentinel value of some kind?
> Representing game state?  There may be an easier way than a full on
> custom type.  Sometimes just a sentinel object is sufficient.  Or an
> enumeration.

they're not sentinels; they're the maximum and minimum of the extended real 
numbers; the point is that, no matter how boards are evaluated (which is, of 
course, subject to change), a won game is always the most valuable and a lost 
game is always the least valuable; ordinary real numbers could be used for the 
purpose, but in that case i would have to figure out the maximum and minimum of 
the heuristic values the script assigns and then add/subtract one (for example) 
to get the value of a won/lost game

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-27 Thread namenobodywants
On Monday, November 27, 2017 at 2:10:56 AM UTC-8, Chris Angelico wrote:

> Or you could use the floating-point values for positive and negative
> infinity

perfecto! thank you!

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-27 Thread namenobodywants
On Sunday, November 26, 2017 at 7:09:25 PM UTC-8, Michael Torrie wrote:

> So you are using this Infinity class as a sentinel value of some kind?
> Representing game state?  There may be an easier way than a full on
> custom type.  Sometimes just a sentinel object is sufficient.  Or an
> enumeration.

they're not sentinels; they're the maximum and minimum of the extended real
numbers; the point is that, no matter how boards are evaluated (which is, of
course, subject to change), a won game is always the most valuable and a lost
game is always the least valuable; ordinary real numbers could be used for the
purpose, but in that case i would have to figure out the maximum and minimum of
 the heuristic values the script assigns and then add/subtract one (for
example) to get the value of a won/lost game

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: connect four (game)

2017-11-27 Thread namenobodywants
On Monday, November 27, 2017 at 2:10:56 AM UTC-8, Chris Angelico wrote:

> Or you could use the floating-point values for positive and negative
> infinity

perfecto! thank you!

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


correctness proof for alpha-beta algorithm

2017-12-18 Thread namenobodywants
hi all

can anybody tell me where to look for a proof of the correctness of a 
minimax/negamax algorithm with alpha-beta pruning? thanks if you can help

peace
stm
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: correctness proof for alpha-beta algorithm

2017-12-19 Thread namenobodywants
On Monday, December 18, 2017 at 10:16:07 PM UTC-8, Terry Reedy wrote:

> Where or how have you looked so far?  How formal do you want?

i want full-on formal with lots of rigor and every possible detail spelled out; 
i've looked in a couple of books but my best lead so far is a paper by knuth 
called "an analysis of alpha-beta pruning" - what i need is along those lines 
but with just a few more of the details spelled out

peace
stm

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: correctness proof for alpha-beta algorithm

2017-12-20 Thread namenobodywants
On Tuesday, December 19, 2017 at 3:28:39 PM UTC-8, Steve D'Aprano wrote:

> Does this have anything specifically to do with Python programming?

i'm working on a game-playing script (ie: in python), i want to incorporate 
pruning into my search algorithm, and i'd like to understand why it works; i'm 
not sure if that counts

> If not, why are you asking here? Do you think that Python programmers are
> especially well-known for their hard-core formal academic methodology?

maybe i just think python programmers are smart or well-informed or something 
like that

> We're pretty accepting of off-topic posts here, especially when they evolve
> naturally from an on-topic post. But in future, if you're going to *start* an
> off-topic thread from the first post, it would be polite to label it such
> with an "[OT]" or "Off-topic" prefix to the subject line.

can do

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: correctness proof for alpha-beta algorithm

2017-12-20 Thread namenobodywants
On Tuesday, December 19, 2017 at 5:34:17 PM UTC-8, Paul Rubin wrote:

> It frankly sounds like homework.

https://en.wikipedia.org/wiki/Theorem
-- 
https://mail.python.org/mailman/listinfo/python-list


unintuitive for-loop behavior

2016-09-29 Thread namenobodywants
hello pythonistas

i've had a nodding acquaintance with python for some time, and all along i 
assumed that for-loops got a namespace of their own; now i'm reading up on the 
language and i find out that's not the case: the loop variable gets put into 
the enclosing namespace, overwriting any former value that was already there; 
of course i realize there are situations where one is interested in the value 
that a loop variable has after the loop has been exited, but this behavior 
seems grossly unintuitive to me: has there ever been any discussion of giving 
for-loops the option of running in namespaces of their own? 

and it gets even worse; consider the following means of raising an exception:

#)-- begin code

def powerfunction(exponent): 
return lambda base: (base ** exponent)

p1 = [powerfunction(exponent) for exponent in range(9)]
p2 = [lambda base: (base ** exponent) for exponent in range(9)]

assert p1[3](4) == p2[3](4)

#) end code

apparently the problem is that "exponent" gets evaluated when the relevant 
lambda function is run, not when it's defined, but no binding for "exponent" 
gets put into the enclosing namespace: it seems that python remembers this 
ghostly "exponent" for me on the theory that i don't WANT "p1" and "p2" to be 
the same; can anyone help to reconcile me to this semantics?

thanks if you can help
stm









-- 
https://mail.python.org/mailman/listinfo/python-list


tkinter callbacks stop working

2016-10-21 Thread namenobodywants
hello pythonistas

the script below plays tictactoe; everything works; but if i replace the block 
at the bottom

if True:


with this instead

def function():

function()

then the tkinter callbacks don't work anymore; can anybody make sense of this? 
thanks if you can help

peace
stm

ps: here's the code...


ex, oh, blank = 'XO '

rows  = [[3*i + j for j in range(3)] for i in range(3)]
columns   = [[3*i + j for i in range(3)] for j in range(3)]
diagonals = [[3+3, 4, 5-3], [3-3, 4, 5+3]]
lines = rows + columns + diagonals

putmark= lambda board, square, mark: board[:square] + mark + board[square + 
1:]
getblanks  = lambda board: [square for square in range(9) if 
board[square]==blank]
getmover   = lambda board: ex if board.count(ex)==board.count(oh) else oh
getlines   = lambda board: [[board[square] for square in line] for line in 
lines]
getwinners = lambda board: [player for player in [ex, oh] if [player] * 3 in 
getlines(board)]

def evaluate(board):
winners  = getwinners(board)
mover= getmover(board)
blanks   = getblanks(board)
value= (+1) if winners==[ex] else (-1) if winners==[oh] else 0
optimum  = max  if mover  == ex  else min  if mover  == oh  else None
if winners or not blanks: return value, []
values   = [evaluate(putmark(board,square,mover))[0] for square in blanks]
optimal  = optimum(values)
return optimal, [square for (index, square) in enumerate(blanks) if 
values[index]==optimal]

isvalid   = lambda board: len(getwinners(board)) < 2 and 
board.count(ex)-board.count(oh) in {0,1}
cartesian = lambda strings: [''] if not strings else [x + ys for x in 
strings[0] for ys in cartesian(strings[1:])] 
getmoves  = lambda: {board: evaluate(board)[1] for board in cartesian([marks] * 
9) if isvalid(board)}

def getmove(board):
from random import choice
blanks = getblanks(board)
evens  = [square for square in blanks if (square % 2)==0]
return choice(evaluate(board)[1]) if len(blanks)<8 else 4 if 4 in blanks 
else choice(evens)

def getdisplay(board):
template  = ' {} | {} | {} '
separator = '\n---\n'
return separator.join(template.format(*(board[square] for square in row)) 
for row in rows)

def getstatus(board):
winners   = getwinners(board)
numblanks = board.count(blank)
if winners:  return winners[0] + ' wins' 
if numblanks==0: return 'draw'
if numblanks==9: return 'X goes first'
else:return getmover(board) + ' goes next'


show = lambda board: print('\n' + getdisplay(board) + '\n\n' + getstatus(board) 
+ '\n')

def newgame():
global board
board = blank * 9
show(board)

def makemove():
global board
board = board if getwinners(board) or blank not in board else 
putmark(board, getmove(board), getmover(board))
show(board)

def takemove(square):
global board
board = board if getwinners(board) or board[square] != blank else 
putmark(board, square, getmover(board))
show(board) 


show = lambda board: status.set(getstatus(board)) or [squares[i].set(board[i]) 
for i in range(9)]

if True: 

from tkinter import Tk, Frame, Label, Button   

window = Tk()
status = StringVar()
squares= [StringVar() for i in range(9)]

statusframe= Frame(window)
buttonframe= Frame(window)
boardframe = Frame(window)
statuslabel= Label(statusframe)
newgamebutton  = Button(buttonframe)
makemovebutton = Button(buttonframe)
rowframes  = [Frame(boardframe)   for i in range(3)]
squarebuttons  = [Button(rowframes[i//3]) for i in range(9)]

statuslabel .configure(textvariable=status)
newgamebutton   .configure(command=newgame,  text='new 
game')
makemovebutton  .configure(command=makemove, text='make 
move')
for i in range(9): squarebuttons[i] .configure(textvariable=squares[i], 
command=lambda i=i:takemove(i))

statuslabel .configure(padx=0,  pady=10)
boardframe  .configure(padx=20, pady=20)
for button in squarebuttons: button .configure(width=4, height=2)

boardframe  .pack(side=TOP)
buttonframe .pack(side=TOP)
statusframe .pack(side=TOP)
newgamebutton   .pack(side=LEFT)
makemovebutton  .pack(side=RIGHT)
statuslabel .pack(side=TOP)
for frame  in rowframes: frame  .pack(side=TOP) 
for button in squarebuttons: button .pack(side=LEFT) 
  
newgame() 
window.title(' tictactoe')
window.mainloop()


""" #)
""" #)   
-- 
https://mail.python.or

how to get python version ?

2016-01-27 Thread namenobodywants
hi

is there something analogous to sys.platform that lets you get the version of 
python you're using? sorry if the question is too see-spot-run. thanks if you 
can help

peace
stm
-- 
https://mail.python.org/mailman/listinfo/python-list