Last active
August 29, 2015 14:08
-
-
Save oupo/e62e99d3d9165cd90863 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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