Skip to content

Instantly share code, notes, and snippets.

@eric-wood
Created July 19, 2013 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eric-wood/18a456a22d6373ea4ca3 to your computer and use it in GitHub Desktop.
Save eric-wood/18a456a22d6373ea4ca3 to your computer and use it in GitHub Desktop.
Pong, in your terminal
require 'curses'
require 'timeout'
include Curses
PADDLE_HEIGHT = 10
PADDLE_WIDTH = 3
SPEED = 3
def write(x, y, text, color=@color)
Curses.attron(color_pair(color))
Curses.setpos(y, x)
Curses.addstr(text)
Curses.attroff(color_pair(color))
end
def init_colors
Curses.init_pair(COLOR_RED, COLOR_RED, COLOR_RED)
Curses.init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_CYAN)
Curses.init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_GREEN)
Curses.init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_WHITE)
@colors = [COLOR_RED,COLOR_CYAN,COLOR_GREEN, COLOR_BLACK]
end
def init_screen
Curses.noecho
Curses.stdscr.nodelay = true
Curses.curs_set(0)
Curses.init_screen
Curses.start_color
init_colors
Curses.stdscr.keypad(true)
begin
yield
ensure
Curses.close_screen
end
end
def update
Curses.clear
(0..PADDLE_WIDTH).each do |w|
(0..PADDLE_HEIGHT).each do |h|
write(0+w, @p1+h, '*')
write(@width-w, @p2+h, '*')
end
end
write(@ball[0], @ball[1], '*', @colors[1])
write(@width/2, 1, "#{@score[0]} | #{@score[1]}", @colors.last)
Curses.refresh
end
def reset_ball
@ball = [@width/2, @height/2]
@dx = @rand.sample
@dy = @rand.sample
end
init_screen do
@width = Curses.cols - 1
@height = Curses.lines
@p1 = @p2 = @height/2 - PADDLE_HEIGHT
@delay = 0.05
@last_update = Time.now
@color = @colors.first
@score = [0,0]
@rand = [-2, -1, 1, 2]
reset_ball
update
loop do
case Curses.getch
when Curses::Key::UP then @p1 -= SPEED unless @p1 <= 0; update
when Curses::Key::DOWN then @p1 += SPEED unless @p1+PADDLE_HEIGHT > @height; update
when Curses::Key::LEFT then @p2 -= SPEED unless @p2 <= 0; update
when Curses::Key::RIGHT then @p2 += SPEED unless @p2+PADDLE_HEIGHT > @height; update
end
if Time.now - @last_update > @delay
@ball[0] += @dx
@ball[1] += @dy
x, y = @ball
in_p1 = y >= @p1 && y <= @p1+PADDLE_HEIGHT
in_p2 = y >= @p2 && y <= @p2+PADDLE_HEIGHT
if x <= 0
@score[1] += 1
reset_ball
elsif x >= @width
@score[0] += 1
reset_ball
end
@dx = -@dx if (x <= PADDLE_WIDTH && in_p1) || (x >= @width - PADDLE_WIDTH && in_p2)
@dy = -@dy if (y <= 0 || y >= @height - 1)
update
@last_update = Time.now
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment