Created
August 16, 2013 18:28
-
-
Save snipsnipsnip/6252296 to your computer and use it in GitHub Desktop.
n-back.rb (脳トレの記憶計算ゲームやっつけ)
This file contains hidden or 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
=begin | |
made with dotgame: https://gist.github.com/962107 | |
参考: http://www.nintendo.co.jp/3ds/asrj/movie/movie.html?mov=3back | |
nバックは20+2n問出るのかな | |
nバックでは、m番目の問題を見ながら(n-m)番目の問題に答える | |
問題は上から流れてくる | |
each_consみたいな具合 | |
problem ∈ { (a, op, b, a op b) | a, b, a op b ∈ {0..9}, op ∈ {+, -} } | |
answer ∈ {タイムアップ, パス, 0..9} | |
=end | |
class ProblemQueue | |
def initialize(back) | |
@back = back | |
@q = [] | |
@problems = enum_for(:each_problem).to_a | |
@answer = nil | |
@moving = false | |
@y = 0 | |
@q.unshift rand(@problems.size) | |
end | |
def tick | |
if @moving | |
@y += 1 | |
if @y % 6 == 0 | |
@q.pop unless @q.size < @back + 3 | |
@q.unshift rand(@problems.size) | |
@moving = false | |
end | |
end | |
end | |
def draw | |
y = @y % 6 - 5 | |
current = @back + (@moving ? 0 : 1) | |
@q.each_with_index do |problem_number, i| | |
problem = @problems[problem_number] | |
case i | |
when current | |
text "???=", 1, y + i * 6, 1, blue | |
#text "#{problem[0..2]}=#{problem[3]}", 1, y + i * 6, 1, blue | |
when current + 1, current + 2 | |
answer = i == current + 1 ? @answer : @prevanswer | |
color = problem[3] == answer ? Color(0, 200, 0) : red | |
text "#{problem[0..2]}=#{problem[3]}", 1, y + i * 6, 1, color | |
when 1, 0 | |
text "#{problem[0..2]}=", 1, y + i * 6, 1, black | |
else | |
text "???=?", 1, y + i * 6, 1, black | |
end | |
end | |
draw_curtain | |
end | |
def shift(answer) | |
return if @moving | |
@moving = true | |
return if @q.size < @back + 2 | |
@prevanwer = @answer | |
@answer = answer | |
current_problem = @problems[@q[@back + 1]] | |
current_problem[3] == answer | |
end | |
private | |
def draw_curtain | |
return if @back <= 1 | |
curtain_height = (@back - 1) * 6 - 1 | |
d, m = curtain_height.divmod(6) | |
y = -@y % 12 | |
d.times do |i| | |
image tile, 0, 7 + i * 6, {:src_height => 6, :src_y => (y + i * 6) % 12} | |
end | |
image tile, 0, 7 + d * 6, {:src_height => m, :src_y => (y + d * 6) % 12} | |
end | |
def tile | |
@tile ||= make_tile | |
end | |
def make_tile | |
phase = 6 | |
tile = make_texture(screenw, phase * 3) | |
tile.fill white | |
tile.square 0, phase, tile.width, phase, gray | |
tile | |
end | |
def each_problem | |
[:+, :-].each do |op| | |
(0..9).each do |a| | |
(0..9).each do |b| | |
c = a.__send__(op, b) | |
if 0 <= c && c <= 9 | |
yield a, op, b, c | |
end | |
end | |
end | |
end | |
end | |
end | |
def make_numkeys | |
numkeys = (0..9).map {|d| [:"numpad#{d}", :"d#{d}"] } | |
def numkeys.get_pressed | |
each_with_index {|v, i| return i if release?(v[0]) || release?(v[1]) } | |
return -1 if spacerelease? || enterrelease? || separatorrelease? | |
nil | |
end | |
numkeys | |
end | |
def make_backkeys | |
keymap = [ | |
[%w[divide slash backslash openbrackets], -1], | |
[%w[multiply quotes closebrackets], 1], | |
[%w[pageup], 3], | |
[%w[pagedown], -3], | |
] | |
backkeys = keymap.map {|keys, diff| keys.map {|key| [key.intern, diff] } }.flatten(1) | |
def backkeys.get_pressed | |
entry = find {|key, _| release? key } and entry[1] | |
end | |
backkeys | |
end | |
back = 2 | |
numkeys = make_numkeys | |
backkeys = make_backkeys | |
begin | |
queue = ProblemQueue.new(back) | |
total_count = -back | |
correct_count = 0 | |
rescale = false | |
main(31, (back + 2) * 6 - 1, 26, {:title => "テンキーや数字キーで回答, Spaceでパス"}) { | |
queue.tick | |
queue.draw | |
if diff = backkeys.get_pressed | |
back += diff | |
back = 1 if back < 1 | |
queue = ProblemQueue.new(back) | |
total_count = -back | |
correct_count = 0 | |
rescale = true | |
break | |
end | |
if answer = numkeys.get_pressed | |
if total_count >= 0 | |
correct_count += 1 if queue.shift(answer) | |
title "%d 問目回答中 (%d 問中 %d 問正解: 正解率 %.0f%%)" % [total_count + 1, total_count, correct_count, correct_count.to_f * 100 / total_count] | |
else | |
queue.shift(nil) | |
end | |
total_count += 1 | |
end | |
} | |
end while rescale |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment