------art_4466_12379084.1134426269894
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Of course I introduced an error while cleaning up my code:
That will teach me to skip unit tests...

in AdamsPlayers.rb, line 111
			i = best_move(b) if taketurn
should be
			m = best_move(b) if taketurn

-Adam.


On 12/12/05, Adam Shelly <adam.shelly / gmail.com> wrote:
> Here are my Kalah Players.

------art_4466_12379084.1134426269894
Content-Type: application/x-ruby; name=AdamsPlayers.rb
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="AdamsPlayers.rb"


#Adapter class - rotates the board so that player's Kalah is always 6
class KalahPlayer < Player
	def choose_move
	  n  @sidealahGame::TOP) ? 7 : 0
		@board  game.board
		@board  board.rotate n
		return get_move + n
	end
	
	#simulate a move
	def simulate board,i
		b  oard.dup
		stones,b[i]],0
		while stones > 0
			i   if (i+ >12
			b[i]+			stones-		end
		if (0..5)i and b[i]
			b[6]+ b[i]+b[opposite(i)])
			b[i]¡¼opposite(i)]		end
		b
	end
	def opposite n
		12-n
	end
	
end

#Some helpers in Array
class Array
	def rotate n
		a ¥ßp
		n.times do a << a.shift end
		a
	end
	def sum
		inject(0){|s,e|s+	end
	#choose randomly between all items with given value
	def random_index value
		n
nd(find_all{|e|ealue}.size)
		each_with_index{|e,i| return i if ealue and (n-<0 }
	end
end

#### Some simple players for testing:
class RemoveRightKalahPlayer < KalahPlayer
	def get_move
			5.downto(0) {|i| return i if @board[i]>0 }
	end
end
class RemoveHighKalahPlayer < KalahPlayer
	def get_move
			myboard  board[0,6]
			myboard.index(myboard.max)
	end
end
class RemoveRandomHighKalahPlayer < KalahPlayer
	def get_move
			myboard  board[0,6]
			myboard.random_index(myboard.max)
	end
end
class RemoveLowKalahPlayer < KalahPlayer
	def get_move
			myboard  board[0,6].select{|e| e>0}
			@board[0,6].index(myboard.min)
	end
end
class RemoveRandomLowKalahPlayer < KalahPlayer
	def get_move
			myboard  board[0,6].select{|e| e>0}
			@board[0,6].random_index(myboard.min)
	end
end

class ScoreKalahPlayer < KalahPlayer
	def get_move
		possible_scores  0..5).map{|i| score_for i}
		possible_scores.index(possible_scores.max)
	end
	def score_for i
	  return -1 if @board[i] 0
		simulate(@board,i)[6]-@board[6]
	end
end


### Some better players

#Tries to find the biggest increase in score for a turn
class DeepScoreKalahPlayer < KalahPlayer
	def get_move
		best_move(@board)
	end
	def best_move board
		possible_scores  0..5).map{|i| score_for(board,i)}
		possible_scores.index(possible_scores.max)
	end
	
	#find the increase in score if we make move m
	def score_for board,m
		return -100 if board[m]<1  						  #flag invalid move
	  b, taketurn   oard,true
		while taketurn
			taketurn  ((b[m]+m)%14 6)  #will we land in kalah?
			b  imulate b,m                               
			m  est_move(b) if taketurn             
		end
		b[6]-board[6]                                 #how many points did we gain?
	end
	
end


#Tries to find the biggest increase in score for a turn
#subtracts opponent's possible score
class APessimisticKalahPlayer < DeepScoreKalahPlayer
	MaxDepth  
	def get_move
	  @level		best_move(@board)
	end
	def best_move board
		return super(board) if (@level > MaxDepth)
		@level+		possible_scores  0..5).map{|i| 
			score_for(board,i) - worst_case(simulate(board,i)) 
		}
		@level-		possible_scores.random_index(possible_scores.max)
	end
	#biggest score the opponent can get on this board
	def worst_case board
		worst  
		opp_board  oard.rotate 7
		6.times {|i|
				s  core_for(opp_board, i)
				worst   if worst < s
			}
			worst
	end
end




------art_4466_12379084.1134426269894--