# Copyright 2006 Michael Lewis # Distributed under the terms of the GNU General Public License v2 require "UserPlayer" require "Table" module TestGame @tc = [[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,10],[5,10],[6,10],[7,10], [11,2],[11,3],[11,4],[11,5],[11,6],[11,7],[11,8], [2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9],[10,10],[11,11]] def TestGame.tc( i ) h = Hand.new h.add_card @tc[i][0] h.add_card @tc[i][1] h end @hl = nil @testCount = 0 def TestGame.hl @hl end def TestGame.getTestHand first_card if @hl.nil? @hl = (2..11).collect + [10,10,10] end hand = ( Hand.new << first_card ) hand.add_card( @hl[ ( @testCount % @hl.length ) ] ) @testCount += 1 if @testCount > @hl.length ** 2 hll = Array.new while !@hl.empty? hll << @hl.slice!( rand( @hl.length ) ) end @hl = hll end @testCount = @testCount % ( @hl.length ** 2 ) return hand end def TestGame.allsame( a ) el1 = a[0] return false if a[0].nil? a.each do |el| return false if el != el1 el1 = el end return true end def TestGame.comp( t, p, precision, test_move, dealer_card, phand, ph ) tries = 13 * 8 comp = Array.new comp.fill( nil, 0..precision ) while !( TestGame.allsame comp[0..precision] ) p.high_edge tries tries.times { t.round( TestGame.getTestHand( dealer_card + 2 ), phand ) } edge1 = p.player_edge p.high_edge tries move1 = p.mt[dealer_card][ph] p.mt[dealer_card][ph] = test_move tries.times { t.round( TestGame.getTestHand( dealer_card + 2 ), phand ) } p.mt[dealer_card][ph] = move1 edge2 = p.player_edge tries = ( ( 1.125 * tries ) / 13 ).to_i * 13 comp.unshift edge1 <=> edge2 #if the length is above this, just find the mean and return that #let's just use the first half if comp.length > precision ** 2 s = 0 comp[0..precision].each { |i| s += i } return s end end return edge1 <=> edge2 end def TestGame.findoptimal( precision = 8 ) t = Table.new( -1, 0, 0 ) p = Player.new t.add_player p #reset the player's move table to all hits p.mt.each { |i| 27.times { |j| i[j] = "h" } } ["s","d"].each do |move| (0..9).collect.reverse.each do |ph| phand = TestGame.tc ph (0..9).each do |dealer_card| diff = TestGame.comp( t, p, precision, move, dealer_card, phand, ph ) p.mt[dealer_card][ph] = move if diff < 0 print p.mt[dealer_card][ph] + " " end puts "" end puts "--" (10..16).collect.reverse.each do |ph| phand = TestGame.tc ph (0..9).each do |dealer_card| diff = TestGame.comp( t, p, precision, move, dealer_card, phand, ph ) p.mt[dealer_card][ph] = move if diff < 0 print p.mt[dealer_card][ph] + " " end puts "" end puts "--" (17..26).collect.reverse.each do |ph| phand = TestGame.tc ph (0..9).each do |dealer_card| diff = TestGame.comp( t, p, precision, move, dealer_card, phand, ph ) p.mt[dealer_card][ph] = move if diff < 0 print p.mt[dealer_card][ph] + " " end puts "" end puts "===" end #test for splits move = "l" (17..26).collect.reverse.each do |ph| phand = TestGame.tc ph (0..9).each do |dealer_card| diff = TestGame.comp( t, p, precision, move, dealer_card, phand, ph ) p.mt[dealer_card][ph] = move if diff < 0 print p.mt[dealer_card][ph] + " " end puts "" end puts "==============" p.mt.transpose.each { |a| puts a.join( " " ) } p.mt end def TestGame.runits( t1, t2, p1, p2 ) i = 0 matches = 0; p1.low_edge p2.high_edge while matches < 3 if ( p1.house_edge - p2.house_edge ).abs < 0.0001 matches += 1 else matches = 0 end 100.times { t1.round } 100.times { t2.round } i += 100 if i % 1000 == 0 puts "r: " + i.to_s puts "p1 " + p1.house_edge.to_s puts "p2 " + p2.house_edge.to_s end end return i end def TestGame.user_game t = Table.new( 6, 1.0, 100.0 ) p = UserPlayer.new t.add_player p t end def TestGame.go( nRounds ) t = TestGame.user_game nRounds.times { t.round } end end