jesusdsc / Conecta4

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

#Conecta 4

###Heuristica.

Empezamos a hacer una heuristica totalmente aleatoria para la dificultad facil. De esta forma en caso de que el oponente se estrese con las otras dificultades puede jugar en facil y sentirse bien consigo mismo.

def heuristicRT(state):
	return randint(-2500, 2500)

Para la dificultad normal, mejoramos la heuristica previa utilizando el utility. De esta forma, si la maquina puede ganar, gana y en caso de que el oponente pueda ganar, bloquea. Dentro de la aleatoriedad hace jugadas buenas y puede hacer pasar un mal momento al oponente.

def heuristicRP(state):
	if state.utility == 1:
		return infinity
	if state.utility == -1:
		return -infinity
	return randint(-2500, 2500)

Para la ultima dificultad (dificil) ya empezamos a plantear una heuristica que escogiese el mejor estado posible. Haciendo la diferencia entre el coste de la maquina y el humano, podemos observar quien tiene la ventaja. En caso de que sea positivo, la maquina tendra ventaja y en caso contrario sera el humano quien la tenga.

def heuristicN(state):
	if state.utility == 1:
		return infinity
	if state.utility == -1:
		return -infinity
	return coste(state, 'X') -  coste(state, 'O')

En esta funcion, llamamos a los metodos (modificados) del tic tac toe.

def coste(state, player):
	"""If X wins with this move, return 1; if O return -1; else return 0"""
	cost = 0
	list_legalmoves = legal_moves(state)
	for move in list_legalmoves:
		cost += k_in_row(state.board, move, player, (0, 1)) #arriba
		cost += k_in_row(state.board, move, player, (1, 0)) #derecha
		cost += k_in_row(state.board, move, player, (1, 1)) #arriba-der
		cost += k_in_row(state.board, move, player, (1, -1)) #abajo-der
	return cost

Con esto obtenemos los posibles movimientos a realizar.

def legal_moves(state):
        "Legal moves are any square not yet taken."
        return [(x, y) for (x, y) in state.moves
                if y == 1 or (x, y-1) in state.board]

Aqui miramos en horizontal, vertical y posibles diagonales. En caso de encontrar una ficha nuestra sumamos 100 al valor a devolver y tambien aumentamos en 1 una variable que nos dice cuantas fichas tenemos alineadas para asi saber los posible cuatro en raya que tenemos. Damos prioridad al bloqueo de nuestro adversario humano.

def k_in_row(board, move, player, (delta_x, delta_y)):
	x, y = move
	n = 0
	ac = 0
	while (board.get((x, y)) == player) or (board.get((x, y))  == None)  and x < 8 and y < 7:
		if board.get((x, y))  == None:
			n += 50
		if board.get((x, y))  == player:
			n += 100
			ac += 1
		x, y = x + delta_x, y + delta_y
	x, y = move
	while (board.get((x, y)) == player) or (board.get((x, y))  == None) and x > 0 and y > 0:
		if board.get((x, y))  == None:
			n += 50
		if board.get((x, y))  == player:
			n += 100
			ac += 1
		x, y = x - delta_x, y - delta_y
	if ac == 3:
		if player == 'X':
			n *= 6
		else:
			n *= 12
	if ac >= 4:
		if player == 'X':
			n *= 9
		else:
			n *= 18
	return n

###Dificultades. Aqui escogemos las dificultades .

def selectDifficulty(state, game):
    print "Seleccione dificultad: "
    print "1. Facil   ||   2. Medio   ||   3. Dificil"
    dificultad = raw_input("Dificultad: ")
    if dificultad == '1':
        return heu.heuristicRT
    else:
        if dificultad == '2':
            return heu.heuristicRP
        else:
            return heu.heuristicN

###Seleccionar jugador Seleccionamos el jugador que jugara primero.

def selectPlayer():
    print "Seleccione el jugador que va primero: "
    print "1. Maquina   ||   2. Humano"
    player = raw_input("Jugador: ")
    if player == '1':
        return 'X'
    else:
        return 'O'

Modificamos el constructor del conecta 4 para asi pasarle el jugador escogido. Poniendo como valor por defecto a la maquina.

"""Conecta 4"""
def __init__(self, h=7, v=6, k=4, player='X'):
        TicTacToe.__init__(self, h, v, k, player)
"""Tic Tac Toe"""
def __init__(self, h=3, v=3, k=3, player='X'):
        update(self, h=h, v=v, k=k)
        moves = [(x, y) for x in range(1, h+1)
                 for y in range(1, v+1)]
        self.initial = Struct(to_move=player, utility=0, board={}, moves=moves)
def humanVsMachine():
    player = selectPlayer()
    game = games.ConnectFour(h=7, v=6, k=4, player=player)
    state = game.initial
    heu = selectDifficulty(state, game)
    while True:
        print "Jugador a mover:", game.to_move(state)
        game.display(state)

        if player == 'O':
            x = checkValidMove()
            y = -1
            legal_moves = game.legal_moves(state)
            for lm in legal_moves:
                if lm[0] == x:
                    y = lm[1]
            state = game.make_move((x, y), state)
            player = 'X'
        else:
            print "Thinking..."
            move = games.alphabeta_search(state, game, d=5, cutoff_test=None, eval_fn=heu)
            state = game.make_move(move, state)
            player = 'O'
        print "-------------------"
        if game.terminal_test(state):
            game.display(state)
            print "Final de la partida"
            break        

Entre otras cosas podemos jugar contra otro humano.

def humanVsHuman():
    player = selectPlayer()
    game = games.ConnectFour(h=7, v=6, k=4, player=player)
    state = game.initial
    while True:
        print "Jugador a mover:", game.to_move(state)
        game.display(state)
        if player == 'O':
            col_str = raw_input("Movimiento: ")
            coor = int(str(col_str).strip())
            x = coor
            y = -1
            legal_moves = game.legal_moves(state)
            for lm in legal_moves:
                if lm[0] == x:
                    y = lm[1]
            state = game.make_move((x, y), state)
            player = 'X'
        else:
            col_str = raw_input("Movimiento: ")
            coor = int(str(col_str).strip())
            x = coor
            y = -1
            legal_moves = game.legal_moves(state)
            for lm in legal_moves:
                if lm[0] == x:
                    y = lm[1]
            state = game.make_move((x, y), state)
            player = 'O'
        print "-------------------"
        if game.terminal_test(state):
            game.display(state)
            print "Final de la partida"
            break

O ver como juega la maquina "aleatoria" contra la maquina que "piensa"

def machineVsMachine():
    game = games.ConnectFour(h=7, v=6, k=4)
    state = game.initial
    player = 'X'
    while True:
        print "Jugador a mover:", game.to_move(state)
        game.display(state)

        if player == 'O':
            print "Don't Think, Just ACT"
            move = games.alphabeta_search(state, game, d=2, cutoff_test=None, eval_fn=heu.heuristicRIA)
            state = game.make_move(move, state)
            player = 'X'
        else:
            print "Thinking..."
            move = games.alphabeta_search(state, game, d=3, cutoff_test=None, eval_fn=heu.heuristicN)
            state = game.make_move(move, state)
            player = 'O'
        print "-------------------"
        if game.terminal_test(state):
            game.display(state)
            print "Final de la partida"
            break

About


Languages

Language:Python 100.0%