Skip to content

Instantly share code, notes, and snippets.

@Caaz
Forked from mbartlet/game.rb
Created February 10, 2017 01:04
Show Gist options
  • Save Caaz/27daf1e79f93acd88166519973bb1885 to your computer and use it in GitHub Desktop.
Save Caaz/27daf1e79f93acd88166519973bb1885 to your computer and use it in GitHub Desktop.
require_relative 'nim.rb'
nim = Nim.new
print "Please select board configuration: (0: [4,3,7], 1: [1,3,5,7]): "
choice = Integer(gets.chomp) rescue nil
while !(choice.match(/0|1/))
puts "Invalid input"
puts "Please select board configuration: (0: [4,3,7], 1: [1,3,5,7]): "
choice = Integer(gets.chomp) rescue nil
end
nim.getBoard(choice)
puts "Select AI type:"
_AIs = Array.new
Player.descendants.each_with_index do |c, i|
_name = c.name.match(/.*_computer\Z/)
_AIs << _name
puts "#{i}: #{_name}"
end
choice = Integer(gets.chomp) rescue nil
while !(choice)
puts "Invalid input"
puts "Select AI type: "
choice = Integer(gets.chomp) rescue nil
end
nim.addPlayer(Human.new)
nim.addPlayer(eval("#{_AIs[choice]}.new"))
nim.start
class Nim
def initialize
@boards = [[1,3,5,7],[4,3,7]]
@players = []
end
###
def getBoard(i = nil)
i = rand(@boards.size) unless i
@board = []
([email protected]).each do |j|
@board << "|"*j
end
end
###
def start()
loser = nil
until loser
loser = turn()
end
puts "#{players[loser].class.name} lost the game."
end
###
def turn
(0..1).each do |i|
@players[i].turn(@board)
lose = true
for x in @board
if x.length > 0
lose = false
break
end
end
return i if lose
end
return nil
end
###
def addPlayer(player)
@players << player
end
###
end
####################################################
class Player
def print
(0..board.length).each do i
puts "#{i}: #{boards[i]}"
end
end
def self.descendants
ObjectSpace.each_object(Class).select { |_class| _class < self }
end
end
####################################################
class Human < Player
def turn(board)
print(board)
puts "Select a row from 0-#{board.length-1}: "
row = Integer(gets.chomp) rescue nil
until (row and board[row] and board[row].length > 0)
puts "Invalid row index or row is empty"
puts "Select a row from 0-#{board.length-1}: "
row = Integer(gets.chomp) rescue nil
end
puts "Take how many sticks?: "
take = Integer(gets.chomp) rescue nil
until take <= board[row].length
board[row] = board[row][0..(take-1)]
end
end
end
####################################################
class SmartComputer < Player
def turn(board)
nim_sum = 0
board.each do |r|; nim_sum ^= r.length
row = 0
take = 1
(0..board.length-1).each do |i|
if num_sum ^ board[i].length < board[i].length
take = board[i].length - (nim_sum ^ board[i].length)
row = i
break
end
end
lessThan2 = lessThanTwo(board,row,take)
if lessThan2
single = 0
(0..(board.length-1)).each do |i|
sticks = board[i].length
sticks -= take if row == i
single += 1 if sticks == 1
end
single %= 2
if single == 0
if board[row].length > 2
take -= 1
else
take = board[row].length
end
end
end
board[row] = board[row][0..(take-1)]
puts "SmartComputer took #{take} sticks from row #{row}."
end
def lessThanTwo(board,row,take)
(0..(board.length-1)).each do |i|
heap = board[i].length
heep -= take if row == i
return false if heap >= 2
end
return true
end
end
end
####################################################
class DumbComputer < Player
def turn(board)
(0..boards.length).each do |r|
take = 1
if boards[r].length > 0
take = 1 + rand(board[r].length-1)
board[row] = board[row][0..(take-1)]
break
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment