Skip to content

Instantly share code, notes, and snippets.

@oupo
Last active August 29, 2015 14:08
Show Gist options
  • Save oupo/e62e99d3d9165cd90863 to your computer and use it in GitHub Desktop.
Save oupo/e62e99d3d9165cd90863 to your computer and use it in GitHub Desktop.
class LCG
def initialize(seed)
@seed = seed
end
def rand()
@seed = (@seed * 0x41c64e6d + 0x6073) % 2**32
@seed >> 16
end
end
class Context
def initialize(seed)
@lcg = LCG.new(seed)
@log = []
@log2 = []
@frame = 0
end
attr_reader :frame
def rand()
@lcg.rand()
end
def log(message)
@log << [@frame, message]
end
def log2(frame, message)
@log2 << [frame, message]
end
def get_log() @log end
def get_log2() @log2 end
def inc_frame(n)
@frame += n
end
end
NPC = Struct.new(:name, :type, :w, :h, :all_directions, :x, :y, :timer, :direction, :state)
UP, DOWN, LEFT, RIGHT = 0, 1, 2, 3
DIRECTION = ["上", "下", "左", "右"]
DX = [ 0, 0, -1, 1]
DY = [-1, 1, 0, 0]
def rand_time(ctx, npc)
time = 16 * (ctx.rand() % 4 + 1)
ctx.log "#{npc.name} time -> #{time}"
time
end
def init(ctx, npcs)
npcs.each do |npc|
if npc.type == :nonmovable then
npc.timer = rand_time(ctx, npc)
end
end
end
def rand_direction(ctx, npc)
direction = npc.all_directions[ctx.rand() % npc.all_directions.size]
ctx.log "#{npc.name} direction -> #{direction}"
direction
end
def advance(ctx, npcs)
npcs.each do |npc|
advance_npc(ctx, npc)
end
end
def advance_npc(ctx, npc)
if npc.type == :nonmovable then
#puts " %s %2d" % [npc.name, npc.timer]
npc.timer -= 1
if npc.timer == 0 then
npc.timer = rand_time(ctx, npc)
direction = rand_direction(ctx, npc)
if npc.direction != direction then
ctx.log2 ctx.frame + 6, "#{npc.name}が#{DIRECTION[direction]}を向く"
end
npc.direction = direction
end
else
#puts " %s %d %2d" % [npc.name, npc.state, npc.timer]
case npc.state
when 0
npc.state = 1
when 1
npc.timer = rand_time(ctx, npc) - 1
npc.state = 2
when 2
npc.timer -= 1
if npc.timer == 0 then
prev_direction = npc.direction
npc.direction = rand_direction(ctx, npc)
if movable(npc)
ctx.log2 ctx.frame + 6, "#{npc.name}が#{DIRECTION[npc.direction]}へ移動"
move(npc)
npc.state = 4
npc.timer = 7
else
if npc.direction != prev_direction then
ctx.log2 ctx.frame + 6, "#{npc.name}が#{DIRECTION[npc.direction]}を向く"
end
npc.state = 0
end
end
when 4
npc.timer -= 1
if npc.timer == 0 then
npc.state = 0
end
end
end
end
def movable(npc)
new_x = npc.x + DX[npc.direction]
new_y = npc.y + DY[npc.direction]
0 <= new_x and new_x < npc.w and 0 <= new_y and new_y < npc.h
end
def move(npc)
npc.x += DX[npc.direction]
npc.y += DY[npc.direction]
end
def nonmovable_npc(name, all_directions, direction)
NPC.new(name, :nonmovable, 0, 0, all_directions, 0, 0, direction, 0)
end
def movable_npc(name, w, h, x, y, direction)
NPC.new(name, :movable, w, h, [UP, DOWN, LEFT, RIGHT], x, y, 0, direction, 0)
end
npcs = [
nonmovable_npc("短パン", [UP, RIGHT], RIGHT),
movable_npc("茶髪", 3, 2, 1, 1, LEFT),
movable_npc("警官", 2, 3, 1, 1, UP),
movable_npc("紳士", 3, 3, 1, 1, LEFT),
nonmovable_npc("婦人", [UP, RIGHT], LEFT),
]
context = Context.new(0xe97e7b6a)
init context, npcs
context.inc_frame 30
500.times do |i|
#puts "NPC loop #{i}"
advance context, npcs
context.inc_frame 2
end
context.get_log2().each {|f,x| puts "%4d %s" % [f, x] }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment