After being throughly impressed by domm's obfu CLI space invaders game I decided to at least try to emulate that sucsess. Here is my almost loathsome CLI game, based off Ti-83 racer, worm, Fly The Copter, etc. etc. Basically you are a ship (>) in a cave and you must avoid hitting the walls for as long as possible using the 'j' key to move down, and the 'u' key to move up.
The program runs. That is the first step. Before I add more features (making keys presses not appear on screen, other ships, barriers not connected to the walls, high score board, etc. etc.), I figure I should get this running respectably well on my G4/500 while running Opera, iTunes (playing the rather raw Eminem Show), AIM, Terminal (obviously), BBEdit, and DynDNS client (and then a ton of deamons, i.e. httpd, sshd, ftpd, etc. etc). I list the programs running to give you an idea of how fast it needs to be. Right now it plays, that is about it. But i really dont know how to do it.
I would hope I could optimize... I dont have a clue. Everything is pretty simple; I can't think of anything. Maybe only doing the shift and pushs on @top and @bottom if there are new values, but the logic for this might be more processor intensive then what I have now. Or in generate_board(), only generate the new column of the board (i.e. shift @board, which removes the first column, then push a new coloum which only represents the newest column). That is the most promising, but it isnt some way to speed up what I am doing, but a new better way to do it If you can't tell, performance isnt something i normally deal with.
Any and all suggestions are welcome, even if they are totally unrelated to preformance. Whatever makes the program better right? Thanks again, and sorry for the rather sparse comments!
#!/usr/bin/perl -w
use strict;
use Term::ReadKey;
my (@top, @bottom, @board, $x, $y, $barrier);
my ($hieght) = 20; #hieght of the cave
my ($width) = 70; #width of the cave
my ($slope) = 80; #how often the standard wall hieght increases by 1
my ($count) = 0; #for waiting till $slope iterations for increasing wa
+ll hieght
my ($wall_hieght) = 1;
my ($score) = 0;
my ($ship_char) = '>';
my ($ship_y) = int(.5 * $hieght); #where the ship is located on the y
+axis
my ($ship_x) = 6;#where the ship is located on the x axis
my ($wall_char) = ':';
my ($clear) = `clear`; #clear the screen and cache the response
for (1 .. $width) {push @top, $wall_hieght;} #initilize the top wall w
+ith the initial wall hieght
for (1 .. $width) {push @bottom, $wall_hieght;}#initilize the bottom w
+all with the initial wall hieght
#main loop
while (1) {
generate_board(\@top, \@bottom, \@board, \$hieght); #generate boar
+d
check_input(\$ship_y); #check for input and move ship if necessary
print $clear; #clear screen
#go through board looking for 1s (represent wall)
for $y (0 .. $#board) {
for $x (0 .. $#{$board[$y]}) {
if ($board[$y][$x] == 1) {
#on crash
if ($y == $ship_y && $x == $sh
+ip_x) {
crash(\$score);
} else {
print $wall_char;
}
} else {
#if ship here
if ($y == $ship_y && $x == $sh
+ip_x) {
print $ship_char;
} else {
print " ";
}
}
}
print "\n";
}
print "Score: " . $score;
$barrier = int(rand($hieght-$wall_hieght))/2+int(.4 * $hieght); #o
+dd way to calculate new barriers, made from approximations and altere
+d after running like 9 bizillion times
shift @top;
shift @bottom;
#only add barriers some times
if (int(rand(5)) == 3) {
#add barrier to top
if (int(rand(2)) == 1) {
push @top, $wall_hieght + $barrier;
push @bottom, $wall_hieght;
} else {
#add barrier to bottom
push @top, $wall_hieght;
push @bottom, $wall_hieght + $barrier;
}
} else {
#no barrier
push @top, $wall_hieght;
push @bottom, $wall_hieght;
}
$count++;
$score++;
#check to make wall hieght greater
if ($count == $slope and $wall_hieght < (int(.5 * $hieght)-1)) {
$wall_hieght++;
$count = 0;
}
}
sub generate_board {
my ($top, $bottom, $board, $hieght) = @_;
my (@tmp_top) = @{$top};
my (@tmp_bottom) = @{$bottom};
my ($check) = 0;
my ($y) = 0;
@{$board} = ();
while ($check < ($#tmp_top+1)) {
$check = 0;
for (0 .. $#tmp_top) {
if ($tmp_top[$_] > 0) {
$$board[$y][$_] = 1;
$tmp_top[$_]--;
} else {
$$board[$y][$_] = 0;
$check++;
}
}
$y++;
}
$check = 0;
$y = $$hieght-1;
while ($check < ($#tmp_bottom+1)) {
$check = 0;
for (0 .. $#tmp_bottom) {
if ($tmp_bottom[$_] > 0) {
$$board[$y][$_] = 1;
$tmp_bottom[$_]--;
} else {
$$board[$y][$_] = 0;
$check++;
}
}
$y--;
}
for $y (0 .. ($$hieght-1)) {
for $x (0 .. ($#tmp_top)) {
$$board[$y][$x] = 0 unless defined($$board[$y][$x]);
}
}
}
sub check_input {
my ($ship_y) = @_;
my ($char);
ReadMode ('cbreak');
if (defined ($char = ReadKey(-1)) ) {
if ($char =~ /[Uu]/) {
$$ship_y--;
} elsif ($char =~ /[Jj]/) {
$$ship_y++;
}
}
ReadMode ('normal');
}
sub crash {
my ($$score) = @_;
print "\ncrash\nScore: $$score\n";
exit();
}
Really sorry about the comments, i am just to tired to continue. Sorry.