Skip to content

Instantly share code, notes, and snippets.

@athom
Created February 11, 2011 05:47
Show Gist options
  • Save athom/821978 to your computer and use it in GitHub Desktop.
Save athom/821978 to your computer and use it in GitHub Desktop.
START = 30
SIZE = 50
WHITE_PIECE = 1
BLACK_PIECE = 2
DEAD_TEST = 3
COUNTED = 4
WHITE_DEAD = 6
BLACK_DEAD = 7 #these are what will go on the board for "temporarily" dead groups
module MyFuncs
def array_deep_copy(from_array)
to_array = Array.new
from_array.each { |ary| to_array += [ary.dup] }
return to_array
end
def array_mul(ary1, ary2)
ret_ary = []
ary1.each do |i|
ary2.each do |i2|
ret_ary = ret_ary.push([i, i2])
end
end
return ret_ary
end
end
class GameUnit
attr_writer :selected, :attacked
def initialize(flag, id, x, y, app, size, game)
@flag = flag
@id = id
@x = x
@y = y
@app = app
@size = size
@game = game
@selected = false
@attacked = false
end
def id
return @id
end
def x
return @x
end
def y
return @y
end
def mark_range (pos)
#if @game.current_player == "white" and @game.same_pos?(pos, "white")
if @game.same_pos?(pos, @game.current_player)
return
end
x = pos[0]
y = pos[1]
@app.stack(:left => START+x*@size, :top => START+y*@size, :width => @size, :height => @size) do
size = @size
shape_clr = @flag == "white" ? rgb(144,255,144,0.5):rgb(47,79,79,0.5)
@app.fill(shape_clr)
shape = @app.rect(2, 2, size-2)
shape.style(:stroke => shape_clr)
@app.fill(shape_clr)
@app.click do |button, x, y|
if button == 1
@x = pos[0]
@y = pos[1]
@game.delete_unit(pos) if @game.same_pos?(pos, @game.get_next_player)
@app.render_field
@game.next_player
@selected = false
end
end
end
end
def unselect
@app.stack(:left => START+@x*@size, :top => START+@y*@size, :width => @size, :height => @size) do
size = @size
shape_clr = @flag == "white" ? "#FFFFFF":"#000000"
text_clr = @flag == "white" ? "#000000":"#FFFFFF"
@app.fill(shape_clr)
shape = @app.oval(1, 1, size-2)
shape.style(:stroke => shape_clr)
text = @app.para(@id.to_s, :top => size/4, :left => size/3, :size => 30, :stroke => text_clr)
text.style(:stroke => text_clr)
shape.style(:stroke => shape_clr)
end
end
def display
@app.stack(:left => START+@x*@size, :top => START+@y*@size, :width => @size, :height => @size) do
size = @size
@shape_clr = @flag == "white" ? "#FFFFFF":"#000000"
@text_clr = @flag == "white" ? "#000000":"#FFFFFF"
@app.fill(@shape_clr)
@shape = @app.oval(1, 1, size-2)
@shape.style(:stroke => @shape_clr)
@text = @app.para(@id.to_s, :top => size/4, :left => size/3, :size => 30, :stroke => @text_clr)
if @attacked
@text.style(:stroke => "#00FF00")
@shape.style(:stroke => "#FF00FF")
end
@app.hover do
if !@selected and @flag == @game.current_player
@text.style(:stroke => "#00FF00")
@shape.style(:stroke => "#FF00FF")
end
end
@app.leave do
if !@selected and @flag == @game.current_player
@text.style(:stroke => @text_clr)
@shape.style(:stroke => @shape_clr)
end
end
@app.click do |button, x, y|
if @game.get_reset_flag
@game.set_reset_flag false
return
end
if button == 1 and @flag == @game.current_player
@app.render_field
@text.style(:stroke => "#FF0000")
@shape.style(:stroke => "#FF0000")
ranges = get_range(@id)
for pos in ranges
mark_range pos
end
@selected = true
end
if button == 3 and @flag == @game.current_player
@selected = false
@app.render_field
end
end
end
end
def get_range(id)
pos_array = []
i = 0
while id >= i
pos_array << [@x+i,@y+(id-i)] if @x+i<6 and @x+i>=0 and @y+(id-i)>=0 and @y+(id-i)<6
pos_array << [@x+i,@y-(id-i)] if @x+i<6 and @x+i>=0 and @y-(id-i)>=0 and @y-(id-i)<6
pos_array << [@x-i,@y+(id-i)] if @x-i<6 and @x-i>=0 and @y+(id-i)>=0 and @y+(id-i)<6
pos_array << [@x-i,@y-(id-i)] if @x-i<6 and @x-i>=0 and @y-(id-i)>=0 and @y-(id-i)<6
i += 1
end
if id > 2
pos_array += get_range(id-2)
end
return pos_array.uniq
end
end
class Game
include MyFuncs
attr_reader :game_over, :current_player, :conflicted, :owning_player
# attr_writer :reset_flag
def set_reset_flag(set)
@reset_flag = set
end
def get_reset_flag
return @reset_flag
end
def get_range(v,x,y)
pos_array = []
i = 0
while v >= i
pos_array << [x+i,y+(v-i)]
pos_array << [x+i,y-(v-i)]
pos_array << [x-i,y+(v-i)]
pos_array << [x-i,y-(v-i)]
i += 1
end
return pos_array.uniq
end
def initialize(size, square_size, app)
@reset_flag = false
@app = app
@size = size
@square_size = square_size
@board = []
@captures = { :black => 0, :white => 0 }
@points = { :black => 0, :white => 0 }
@last_passed = false
@game_over = false
@white_soldiers = []
@black_soldiers = []
for i in 0..@size - 2
@white_soldiers << GameUnit.new("white",@size-1-i,i,0,@app,@square_size, self)
@black_soldiers << GameUnit.new("black",i+1,i,@size - 2,@app,@square_size, self)
end
for i in 0...@size
a = []
for j in 0...@size
a[j] = 0
end
@board[i] = a
end
@current_player = "black"
@history = [{ :board => [], :white_captures => 0, :black_captures => 0 }] #for checking for illegal ko moves and undoing, this will hold hashes of board positions and scores
@move_count = 1
@test_board = array_deep_copy(@board) #for various tests
@owning_player = 0 #for territory counting at end game
@conflicted = false #ditto
end
def reset
@white_soldiers.clear
@black_soldiers.clear
for i in 0..@size - 2
@white_soldiers << GameUnit.new("white",@size-1-i,i,0,@app,@square_size, self)
@black_soldiers << GameUnit.new("black",i+1,i,@size - 2,@app,@square_size, self)
end
@reset_flag = true
end
def show_units()
@white_soldiers.each do |ws|
ws.display
end
@black_soldiers.each do |ws|
ws.display
end
end
def search_unit(pos)
@units = get_next_player == "white" ? @white_soldiers : @black_soldiers
@units.each do |u|
if u.x == pos[0] and u.y == pos[1]
return u
end
end
end
def delete_unit(pos)
@units = get_next_player == "white" ? @white_soldiers : @black_soldiers
@units.each do |u|
if u.x == pos[0] and u.y == pos[1]
@units.delete(u)
if u.id == 1
@game_over = true
if confirm 'game over, ' + @current_player + ' wins the game!! ' + 'play again?'
reset
@game_over = false
else
exit
end
end
end
end
end
def same_pos?(pos, flag)
if flag == "white"
@white_soldiers.each do |ws|
if ws.x == pos[0] and ws.y == pos[1]
return true
end
end
return false
else
@black_soldiers.each do |ws|
if ws.x == pos[0] and ws.y == pos[1]
return true
end
end
return false
end
end
def get_next_player() #I kind of hate myself now
if @current_player == "black"
return "white"
else
return "black"
end
end
def next_player()
if @current_player == "black"
@current_player = "white"
else
@current_player = "black"
end
end
def draw_piece(x, y, color)
clr = "#FFFFFF"
if color == "white"
clr = "#000000"
@app.fill("#FFFFFF")
end
size = @square_size
#@app.oval(START+x*size-(size-2)/2, START+y*size-(size-2)/2, size-2, size-2)
@app.oval(START+x*size, START+y*size, size-2)
@app.fill("#000000")
@app.para("1", :top => START+y*size+size/4, :left => START+x*size+size/3, :size => 30, :stroke => clr)
end
def draw_x(x, y)
size = @square_size
@app.stroke rgb(255,0,0,0.9)
@app.line(START+x*size-size/2-1, START+y*size-size/2-1, START+x*size+size/2-1, START+y*size+size/2-1)
@app.line(START+x*size-size/2-1, START+y*size+size/2-1, START+x*size+size/2-1, START+y*size-size/2-1)
@app.stroke "#000000"
end
def draw()
for i in 0...@size
for j in 0...@size
if @board[i][j] == WHITE_PIECE
draw_piece(i, j, "white")
elsif @board[i][j] == BLACK_PIECE
draw_piece(i, j, "black")
elsif @board[i][j] == WHITE_DEAD
draw_piece(i, j, "white")
draw_x(i, j)
elsif @board[i][j] == BLACK_DEAD
draw_piece(i, j, "black")
draw_x(i, j)
end
end
end
show_units
end
def undo()
@move_count -= 1
previous_move = @history[@move_count]
@board = array_deep_copy(previous_move[:board])
@captures[:black] = previous_move[:black_captures]
@captures[:white] = previous_move[:white_captures]
next_player()
end
def get_player_number(color) #gets the number from the string color
if color == "white"
return 1
elsif color == "black"
return 2
else
return 5
end
end
def play_at_loc(x, y)
@board[x][y] = get_player_number(@current_player)
end
end
Shoes.app :width => 600 , :height => 600 do
@game_size = 7 #default
@square_size = self.height/@game_size
extend MyFuncs
def render_field()
debug @game.current_player
clear do
background rgb(119, 169, 108, 0.8)
x = START
y = START
self.strokewidth(1)
@game_size.times do
line(x, y, x, (@game_size-1)*@square_size+START)
x += @square_size
end
x = START
@game_size.times do
line(x, y, @square_size*(@game_size-1)+START, y)
y += @square_size
end
if @game_size == 9
pt_loc = 3
else
pt_loc = 4
end
oval_size = @square_size/3
if(@game_size == 9)
start_pt = 2
else
start_pt = 3
end
end_pt = @game_size - (start_pt+1)
mid_pt = (start_pt+end_pt)/2
self.strokewidth(2)
@game.draw()
end
end
$app = self
@game = Game.new(@game_size, @square_size, self)
render_field
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment