/usr/share/gcompris/python/connect4p/minmax.py is in gcompris-data 15.02-1.1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | # gcompris - connect4
#
# Copyright (C) 2005, 2008 Laurent Lacheny
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# This code comes from the project 4stattack
# http://forcedattack.sourceforge.net/
#
#########################################################################
# 4st Attack 2 #
#########################################################################
# Created by: #
# Developer - "slm" - Jeroen Vloothuis #
# Graphics - "Korruptor" - Gareth Noyce #
# Music - "theGREENzebra" #
#########################################################################
# Specail thanks: #
# chakie(Jan Elkholm) - letting me "embrace and extend" his gui lib #
# Mighty(Xander Soldaat) - for the Makefile and the Debian packages #
# Han - for the rpms #
# jk - for the FreeBSD port #
# Tjerk Nan - for the Windows version #
# Micon - for the webdesign #
# Everyone in #pygame and the opensource community in general #
#########################################################################
# This software is licensed under the GPL - General Public License #
#########################################################################
import rules
from player import *
from random import *
import copy
from board import *
class Node:
def __init__(self, board, move, player):
self.board = board
#self.parent = parent
self.value = 0
self.childs = []
self.move = move
self.player = player
def __repr__(self):
if self.childs > 1:
number=0
for child in self.childs:
number=number+1
return "Has %s child(s)" % number
return "STATE"
class MinMax(Player):
type = 'AI'
def __init__(self, difficulty, f):
self.search_depth = difficulty
self.f = f
def setDifficulty(self, difficulty):
self.search_depth = difficulty
def evaluate(self, node, player, opponent, depth):
if len(node.childs) > 0:
list = []
for child in node.childs:
list.append(child.value)
if node.player != player:
node.value = min(list)
#print 'min =', node.value,
else:
node.value = max(list)
#print 'max =', node.value,
else:
node.value = self.score(node, player, opponent) / (depth + 1)
def score(self, node, player, opponent):
return int(random() * 100) - 50
def makeBoard(self, move, board, player):
temp_board = copy.deepcopy(board)
temp_board.move(move, player)
return temp_board
def listMoves(self, board, player):
checkmove = rules.isMoveLegal
options = []
for move in range(7):
if checkmove(board, move):
options.append(move)
return options
def statespace(self, node, depth, current_player, player, opponent):
self.f()
if rules.isWinner(node.board, opponent):
#print "a lose up ahead"
node.value = -10000 + depth
return node
elif rules.isWinner(node.board, player):
node.value = 10000 - depth
return node
elif self.listMoves(node.board, 0) < 1:
self.evaluate(node, player, opponent, depth)
return node
elif depth < self.search_depth:
if current_player==2:
next_player = 1
else:
next_player = 2
for move in self.listMoves(node.board, current_player):
node.board.move(move, current_player)
node.childs.append(self.statespace(Node( node.board, move, next_player), depth+1, next_player, player, opponent))
node.board.undomove(move)
self.evaluate(node, player, opponent, depth)
#print 'v=%d p=%d' %(node.value,node.player)
return node
def doMove(self, current_board, player, event):
board = copy.deepcopy(current_board)
if player == 1: opponent = 2
else: opponent = 1
node = Node(board, 0, player)
node = self.statespace( node, 0, player, player, opponent);
bestscore = -100000
best_moves = []
#print "New Round"
for child in node.childs:
#print "Child value=", child.value, "move=", child.board.last_move
if child.value >= bestscore:
#if rules.isMoveLegal(board, child.board.last_move):
if bestscore == child.value:
#print "Move added"
best_moves.append(child.move)
else:
#print "New best move"
bestscore = child.value
best_moves = [child.move]
return best_moves[int(random()*len(best_moves))]
def gameOver(self, move):
return None
#try:
# psyco.bind(MinMax)
# psyco.bind(Node)
#except:
# pass
|