I am a novice functional programmer. So if you find any areas of suggested improvement on my FP skills, do add a comment below.
Below is a sample Tic Tac Toe written using Functional Programming constructs (or at least whatever I understood about them).
Right now, I've implemented only a simple player who basically marks off a cell randomly. It should be possible to define more intelligent players similarly. Hopefully all the comments in the code should be sufficiently self explanatory.
import random import functools import itertools import copy def row_gen(board): """ Generator which returns tuples of tuples. The outer tuple represents a row. The inner tuple represents each cell with its coordinates and data """ return ( tuple((row,col,board[row][col]) for col in range(3)) for row in range(3)) def col_gen(board): """ Generator which returns tuples of tuples. The outer tuple represents a column. The inner tuple represents each cell with its coordinates and data """ return ( tuple((row,col,board[row][col]) for row in range(3)) for col in range(3)) def dia_gen(board): """ Generator which returns two tuples of tuples. The outer tuple represents a diagonal. The inner tuple represents each cell with its coordinates and data """ return ( tuple((i,i,board[i][i]) for i in range(3)), tuple((i,2-i,board[i][2-i]) for i in range(3))) def empty(board): """ Gets a list of all empty cells on the board """ return ( (row,col) for row in range(3) for col in range(3) if board[row][col] == None) def is_empty(board): """ checks if any cell on the board is still empty """ for row in range(3) : for col in range(3) : if board[row][col] is None : return False return True def random_player(chr,board): """Represents a player who randomly marks his next move """ empty_cells = list(empty(board)) play = empty_cells[random.randint(0,len(empty_cells)-1)] board = copy.copy(board) board[play[0]][play[1]] = chr return board def show(board): """ Shows the current representation of the board """ print '+-+-+-+' for row in range(3) : print '|%s|' % '|'.join( board[row][col]if board[row][col] is not None else ' ' for col in range(3)) print '+-+-+-+' if __name__ == '__main__' : # Initialise the board with all values set to None board = list(list(None for i in range(3)) for j in range(3)) show(board) # Initialise the two players. Each is given a separate char player1 = functools.partial(random_player,'X') player2 = functools.partial(random_player,'O') # Setup an iterator to continuously cycle through both players players = itertools.cycle((player1,player2)) # Play game over = False while not over and not is_empty(board) : # Ask the next player to make his move board = players.next()(board) show(board) # Note a cell bag set is all rows, # all cols and all diagonals for cell_bag_set in ( row_gen(board), col_gen(board), dia_gen(board)) : # Note a cell_bag can be a row, column or a dia for cell_bag in cell_bag_set : vals = set(val[2] for val in cell_bag) if len(vals) == 1 and \ vals.__iter__().next() is not None : over = True print 'Over' break
Comments !