From 50e4712545621b47985ccdbf342f1865c4ca7517 Mon Sep 17 00:00:00 2001 From: Rosia E Evans Date: Sun, 1 Dec 2024 16:37:27 +0000 Subject: [PATCH] adds game --- __pycache__/display.cpython-310.pyc | Bin 0 -> 3930 bytes __pycache__/display.cpython-311.pyc | Bin 0 -> 3009 bytes __pycache__/enemy.cpython-310.pyc | Bin 0 -> 1375 bytes __pycache__/enemy.cpython-311.pyc | Bin 0 -> 1545 bytes __pycache__/input.cpython-310.pyc | Bin 0 -> 1165 bytes __pycache__/input.cpython-311.pyc | Bin 0 -> 1799 bytes __pycache__/level.cpython-310.pyc | Bin 0 -> 2364 bytes __pycache__/level.cpython-311.pyc | Bin 0 -> 1492 bytes __pycache__/level_runner.cpython-310.pyc | Bin 0 -> 2093 bytes __pycache__/level_runner.cpython-311.pyc | Bin 0 -> 3564 bytes __pycache__/player_stats.cpython-310.pyc | Bin 0 -> 890 bytes __pycache__/player_stats.cpython-311.pyc | Bin 0 -> 1169 bytes __pycache__/tunnel.cpython-310.pyc | Bin 0 -> 1121 bytes __pycache__/tunnel.cpython-311.pyc | Bin 0 -> 1857 bytes __pycache__/tutorial.cpython-310.pyc | Bin 0 -> 2384 bytes display.py | 101 ++++++++++++++++++++ enemy.py | 24 +++++ input.py | 33 +++++++ level.py | 49 ++++++++++ level_runner.py | 69 ++++++++++++++ main.py | 102 ++++++++++++++++++++ player_stats.py | 17 ++++ tunnel.py | 19 ++++ tutorial.py | 114 +++++++++++++++++++++++ 24 files changed, 528 insertions(+) create mode 100644 __pycache__/display.cpython-310.pyc create mode 100644 __pycache__/display.cpython-311.pyc create mode 100644 __pycache__/enemy.cpython-310.pyc create mode 100644 __pycache__/enemy.cpython-311.pyc create mode 100644 __pycache__/input.cpython-310.pyc create mode 100644 __pycache__/input.cpython-311.pyc create mode 100644 __pycache__/level.cpython-310.pyc create mode 100644 __pycache__/level.cpython-311.pyc create mode 100644 __pycache__/level_runner.cpython-310.pyc create mode 100644 __pycache__/level_runner.cpython-311.pyc create mode 100644 __pycache__/player_stats.cpython-310.pyc create mode 100644 __pycache__/player_stats.cpython-311.pyc create mode 100644 __pycache__/tunnel.cpython-310.pyc create mode 100644 __pycache__/tunnel.cpython-311.pyc create mode 100644 __pycache__/tutorial.cpython-310.pyc create mode 100644 display.py create mode 100644 enemy.py create mode 100644 input.py create mode 100644 level.py create mode 100644 level_runner.py create mode 100644 main.py create mode 100644 player_stats.py create mode 100644 tunnel.py create mode 100644 tutorial.py diff --git a/__pycache__/display.cpython-310.pyc b/__pycache__/display.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f911ae2b3ff4c47bad59d26553788b4761b30bf GIT binary patch literal 3930 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 literal 0 HcmV?d00001 diff --git a/__pycache__/enemy.cpython-310.pyc b/__pycache__/enemy.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ecf4b9cf930372737de7903965ba3137e7a2ebc GIT binary patch literal 1375 zcma)6yKdVs6eabrWyf|L)NRoh(A7htsasJ5D2faLgdo|p5UNPqLiKPdd9abq0kZcC z+Ntm_Y3(O?^VEB=p~aIn?|b!UdB| z@;j(Y!$)LD6OgIc()2lCOWJ^K!Uo`mYyxf)HUT@b1-M1nlI9Q1d>7TYk$#6@dblac^jpRyYZCX?{_2 z1i6Yw8dt5Dw&AmR=T5RjxjM_Ez`fGhSO-ZGrDOMMUQDvoEoNz|;?wHmDpYYcotKUf zQ5qFOn7BK7*5GZv=#k8`de8&qFf$DjB}Ca4BFW?|#&$=Dud^VoMsyR_lboH826WGB~X!itwIA;LJwb0Ml^C=X1~fl7IFDyLA! z)~S`Paa^}B-~}b>vipZDRB>Dr;<4!y3`E_57SgYAe}@gY#-6i_@% literal 0 HcmV?d00001 diff --git a/__pycache__/enemy.cpython-311.pyc b/__pycache__/enemy.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e46f3a08f837d844e16c8aea5d195a067f8a87f GIT binary patch literal 1545 zcmb_b&ubGw6n-I<6og9XKcga87CiY6q@)MQ$@gZuYhYUu^v%w4t@u|2~8 ze$XV5{P|$?6bF6aunsmHfX$9Lz%h0$4Q=6QF&sED(1!io#*|kMZTXCi+f$FBTCkGE z^v4{OjOOvz2L~F=h6cCU0W=Jo<9Z{`ulbJGwbBG|C5>s*(H-Ts&-Ov!NQ;^!f$<0! zgw?A&&RIK685_@?E=@wm-I8?Vkb*5OjqlZV0?(<*AZ#^jn=;szP0wrj+qKPZdnfQ~ z?T+s|?u!1^9Li~Rw;P*6wER|Eh?lb}&(&m3`Gs_>9-PdVqugQfWNra}W`u2odZ<@( zI{-<{Nt1v=E1=ZFy9m9s4LQ%3hmZyBPp%gB zR44?=Xc6Jn1P2jpG33E)7!kZ+jU1MdBNyIoyKAM@MIVYtU0s{EtPkx8>k%4`v1@rh zVM%mA7Yy~ssf~fnkPp0i&=g*_t~s`H7lRY%E>&jRgAEy(hc(R3VO&H zf)W8mj!WmeT8`@qF<|lrYC}5ABfbAMT1r4khW8P0)1+O>*5wRRsDEH^YCU-7w)~4J z+`!oXi9&jIydJZl$|b!5&DV7tW!br^b4ux<>V~%w{y+~hgrC0D3l#q*IZf347AXmc zux#B~esKtY2YM3~l> literal 0 HcmV?d00001 diff --git a/__pycache__/input.cpython-310.pyc b/__pycache__/input.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b32e56da50729c7d77c23ff14f1d99c81284754d GIT binary patch literal 1165 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 SHnt*XJ#gsBrO){{{O^C}6tKGh literal 0 HcmV?d00001 diff --git a/__pycache__/level.cpython-311.pyc b/__pycache__/level.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5404ddd39b7f15ec78216032bcbeffbad19a80a0 GIT binary patch literal 1492 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 literal 0 HcmV?d00001 diff --git a/__pycache__/tunnel.cpython-310.pyc b/__pycache__/tunnel.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..983cca8fc0442c0dd58cc4b5e9002cf689e28113 GIT binary patch literal 1121 zcmZuwPixyS6qn>bakI2ty`4sP8EoLflAU%cVX%$C4xytx1&T42nmX9BBgwFY^pt*q zeS_w>ucYfvz3c<*wD;^LEwlnjPtVftz2EOWm%F=N0^^1LKKV-t`Gbdt!-2ymnED+o zoN$_xf{rOgo8|0`d?Vc9?ls}=ij5uaos!7Eg}Wr8*85S5T7W^1Qgl5WTi_$`3Nogg zj2Wk#T@!$5AjdBEgm=NX&pX%d*yjO&?^yq=mQv&?q`MsqEEncyn0g3{AuF;ZF*U5& z9piGkqF>1Q&J|sfsdMAujWrON^^D(mI%~3Oh(Q!Ky4?qqD6rnwqB3*4BgIb>Ya=R! zv22i*(g{LPX5ETI3g&X1|F-xPKo9mt`Ras?=FBI8o(9 zB}I|R$>3yeE=xHu4YT*{c6aJma~s5QCNmSqKA`9TmVgHIkcM=z->T8y+(Nz@} zB~>LPZv^UrLt~;{x<|Wo5#D9^;EMH?Ftw78YPe1I5Z<@lfGJO*aw~d8xpTvobWI^m zcl6}rQw$!$G69C?9u%8S$uBlzr)|2>jBa|FC@2o=e^7gHv!&4xYPfWd^GutxEUF;_ zX%sOei???)K$JMqz*O~*^D<3xJp^O(!ji~o)$?Z9{MMb8ncQdxv~``EM-lHa4=^Hj za){C$Jc>DrI@k>|DMTFGZX6dSuXD6}aXhP&y#1mON4`X1@x4$`F~0ik1fgHaT9 z`7u&r@A+22p8Tjz>l7G#r!+X?FQG#JHf;A0MMbQmqM+j)1SSNak}gvDnV?HMQZW`7 z^`8Tobu;^XMx7E+^c4%ZrtOQ*Ose>jsNhX8^j&_0eV zte~e~y}(;&Jvx0jVsohX@p#7VVboHb#87X{^2AU+W(MZSjB>6!>%-_B6yNbjb|RN*gR`D zZk!kLYgLoxS=Fv+`G>4pW}0bMtaAS0rn6SH@{XUS#b6oia3ms8eUwSQ|$8{RAiA&VWW9#c(~saODDWFR(5gei*L{ zEe8cHu3mCF1OECM-)R|KKAnWF#KYvh7FzMg=pDa{q|%zkpqz!=*DM7Jqu8CtmyC+- zl&WTJxp8X%9l)+?Ho(bpOGdS%8TK+T;V}-m{W*|r zj<0XTFEqy6)hGPQvmXH2j-H+%$+vnaB2%I~-$N0J3-TBH-}VqJA0>e&?u56%0(ZvC z%af@^&CS63ctq!9DfpXZ#*yL0X8#DJCt{4dXx1H{T{Po{vlmNZ2<0;Qm&^Y9zz09P F{{aWCeD(kU literal 0 HcmV?d00001 diff --git a/__pycache__/tutorial.cpython-310.pyc b/__pycache__/tutorial.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50ce16777352845e10d65ddb89069dc7d1304e4f GIT binary patch literal 2384 zcmb_ePj4eN6!**|(?Echd+<2P zCd!`5=Rhepz5*X*PDq^c6*%#pCuy@q+RcHPc*bwudq2P5^Rpe(Xw(Q?d%t}<__I#P z-zaQeAqZbW%YJ|dCp=Ij2|7W5{ZNHT)QOT(r{v{Gm6Ny=`+iC7B$ZCZ_sgo9)H*fa zkJWBc@6@5c!z;g%PJ>q;lU8jB=%f|o!$sBAE=e(;ub5e6y|)#1!5Xo5x5O?1_I`owtLgyc zyW5QQ%8VR9eZIDV{5r^QY{+kd{MI%jx%wPx*flQ6W%N9nM~kMrv)JSJt^#PGUm2^q z_6$P6efwp&oWOd1=h3nX3vG!jaCY~BcEVC;XwPUT^+?duC9cQiKB^l}sT<0S!f$Fu z1Na2jUtcT_;5EBHrqX4UGkbB2YT9Gk(M$+B8Ny7hhZA%V7Qz>FU=Cl57Nc87Kz&@Z)2H-YKt#X>@qpuz zQl7?*;mDbUIoV@MO)2YRt{J2VlFgU6<;{*M1&&9KYD1k&JWELFgu@1VgiJ6$&hMGo z;p{UDt^+MI98=JgIY89MG_``up7S4(uM|j^ugQUJvW#)KuUAnj0}zb%#e^z325ZPf z=9qPKBHi$qo{z2xrLuPc>7k>P{xX8Tnl5(`>Z5FA$KXpp`Ph^87(J7uN;t&!XMzpT z^yEjVj)B4WWOhg&8Y-Tp%J|F)C!U|T1>iq%My_{xy({HNVAF&L(U)2}p{8A^pDs*#zK<2FMV57o5)?e&Woarj z@8T?5IDm-7HDEDi7RlySJJQ{P5l&lP9SB#*tx{gX@$*RPG>=#D)r%7myx7P&ALz9TMHJN1XGiwGwEs=WAKAXCs(e1+be(?gy87rAONvC;bE#M!5?00y?K_#pO zdvI5vhwWuj9K5K#E#KDG|6{-Ya(leZ2%5nG#8Ft(1A7QzK58}d64rGwD`meJZ!(;h zZ*pqi1ACwHypB^XEKCRNBYpzxyQsvf@UT9g8xIPKyz+Ts_(+LUthuZSk2={4>%r=d F{srG&UBdtX literal 0 HcmV?d00001 diff --git a/display.py b/display.py new file mode 100644 index 0000000..8bba99f --- /dev/null +++ b/display.py @@ -0,0 +1,101 @@ +import curses +from _curses import A_DIM, A_BLINK, A_STANDOUT, A_BOLD +from curses import initscr + +from tunnel import Tunnel + + +class Display: + def __init__(self, scr): + self.scr = scr + curses.noecho() + curses.cbreak() + curses.curs_set(0) + + self.darkness_revealed = False + + def teardown_curses(self): + curses.nocbreak() + curses.echo() + curses.endwin() + + def new_frame(self): + self.scr.clear() + + def display_frame(self): + self.scr.refresh() + + def display_lose_screen(self): + self.scr.addstr(2, 2, "the small creature died") + self.scr.addstr(3, 2, "the tunnel was empty again") + self.scr.addstr(4, 2, "any key to exit") + self.scr.addstr(6, 13, " \\_") + self.scr.addstr(7, 13, "⩍ \\ ") + + def display_win_screen(self): + self.scr.addstr(2, 2, "the small creature explored the whole tunnel") + self.scr.addstr(3, 2, "they had a nice time and were ready to go find another") + self.scr.addstr(4, 2, "but first they wanted to sleep") + self.scr.addstr(5, 2, "any key to exit") + + self.scr.addstr(7, 8, "Z") + self.scr.addstr(8, 7, "zᶻ") + self.scr.addstr(9, 5, "> ᶻ") + + + + # tunnel is 15 long + def display_tunnel(self, tunnel: Tunnel): + player_pos = 15 + y = 3 + x = 2 + + self.scr.addstr(y, x, tunnel.get_as_str(), A_DIM) + self.scr.addch(y, x+player_pos, ">") + + if self.darkness_revealed: + self.scr.addch(y, x+player_pos+1, tunnel.next_step.char) + else: + self.scr.addch(y, x+player_pos+1, "▓", A_DIM) + + self.scr.refresh() + + def display_lives(self, lives): + lives_string = "lives: " + ("v"*lives) + self.scr.addstr(1, 2, lives_string, A_DIM) + + def display_level(self, level): + self.scr.addstr(6, 2, "level: " + str(level), A_DIM) + + def display_steps(self, steps, total_steps): + lives_string = "steps: " + str(steps) + "/" + str(total_steps) + self.scr.addstr(5, 2, lives_string, A_DIM) + + def display_next_level(self): + self.scr.addstr(2, 2, "The tunnel continues") + self.scr.addstr(3, 2, "deeper to the next level") + + self.scr.addstr(5, 12, "⩍") + + + def display_menu_art(self): + self.scr.addstr(1, 13, " \\_") + self.scr.addstr(2, 13, "⩍ \\ <") + + self.scr.addstr(4, 2, "A small creature") + self.scr.addstr(4, 19, "explores", A_BOLD) + self.scr.addstr(4, 28, "a tunnel") + + def display_menu(self, options, index): + y = 7 + x = 13 + for i, option in enumerate(options): + if i == index: + self.scr.addstr(y+i, x-1, ">") + self.scr.addstr(y+i, x, option) + else: + self.scr.addstr(y+i, x, option, A_DIM) + + + +# ---o---o---o->-▓ diff --git a/enemy.py b/enemy.py new file mode 100644 index 0000000..147a00a --- /dev/null +++ b/enemy.py @@ -0,0 +1,24 @@ + +class Enemy: + def __init__(self, char): + self.char = char + self.key = char + +class Empty(Enemy): + def __init__(self): + super().__init__(" ") + self.char = "-" + +class Goblin(Enemy): + def __init__(self): + super().__init__("o") + +class Slime(Enemy): + def __init__(self): + super().__init__("e") + +class KnifeRat(Enemy): + def __init__(self): + super().__init__("c") + + diff --git a/input.py b/input.py new file mode 100644 index 0000000..ac0dd4c --- /dev/null +++ b/input.py @@ -0,0 +1,33 @@ +import curses +from curses import * + + + +class Input: + def __init__(self, scr): + self.scr = scr + halfdelay(10) + + def wait_on_any_key(self) -> int: + try: + key_given = self.scr.getch() + return key_given + except curses.error: + pass + + def wait_on_key(self, key): + try: + key_given = self.scr.getch() + if key_given is None: + return False + if key_given == ord(key): + return True + except curses.error: + pass + + return False + + def wait_indefinitely_for_key(self): + nocbreak() + self.scr.getch() + halfdelay(20) \ No newline at end of file diff --git a/level.py b/level.py new file mode 100644 index 0000000..9ffdae3 --- /dev/null +++ b/level.py @@ -0,0 +1,49 @@ +from math import sqrt +from typing import Union +from enemy import * + +class Level: + def __init__(self, level_gen): + self.level_gen = level_gen + self.steps = 0 + self.length = 40 + + + def get_next_step(self) -> Union[Enemy, None]: + self.steps += 1 + return self.level_gen(self.steps) + + +class LevelLibrary: + def __init__(self, levels): + self.levels = levels + self.current_level = 0 + + def __iter__(self): + return self + + def __next__(self): + next_level = self.get_level(self.current_level) + + if next_level is None: + raise StopIteration + + self.current_level += 1 + return next_level + + def get_level(self, level_number: int) -> Union[Level, None]: + if level_number >= len(self.levels): + return None + else: + return Level(self.levels[level_number]) + + +level_lib = LevelLibrary( +[ + lambda step : Goblin() if step%2==0 else Empty(), + lambda step : Goblin() if step%3==0 else Empty(), + lambda step : Goblin() if step%4==0 else KnifeRat() if step%2==0 else Empty(), + lambda step : Slime() if sqrt((step * 8) + 1).is_integer() else Empty(), + lambda step : KnifeRat() if step%3==0 and step%5==0 else Goblin() if step%3==0 else Slime() if step%5==0 else Empty(), +] +) \ No newline at end of file diff --git a/level_runner.py b/level_runner.py new file mode 100644 index 0000000..2af0dae --- /dev/null +++ b/level_runner.py @@ -0,0 +1,69 @@ +from enum import Enum + +from display import Display +from input import Input +from level import Level +from player_stats import PlayerStats +from tunnel import Tunnel + + +class State(Enum): + GUESSING = 0 + REVEALED = 1 + +class LevelRunner: + + + def __init__(self, disp: Display, inp: Input, player: PlayerStats): + self.disp = disp + self.inp = inp + self.state = State.GUESSING + self.player = player + + def reveal(self): + self.state = State.REVEALED + + def move_to_next_step(self, tunnel: Tunnel, level: Level): + tunnel.append_step(level.get_next_step()) + self.state = State.GUESSING + + + def run_level(self, level: Level, level_number: int): + tunnel = Tunnel() + self.player.lives = 10 + + while True: + self.disp.new_frame() + + if self.player.is_dead(): + return 0 + if level.steps >= level.length: + return 1 + + self.disp.display_lives(self.player.lives) + self.disp.display_steps(level.steps, level.length) + self.disp.display_level(level_number) + + + match self.state: + case State.GUESSING: + self.disp.darkness_revealed = False + self.disp.display_tunnel(tunnel) + self.disp.display_frame() + + guesses_correct = self.inp.wait_on_key(tunnel.next_step.key) + if not guesses_correct: + self.player.lose_life() + else: + # self.player.heal_life() + pass + + self.reveal() + + case State.REVEALED: + self.disp.darkness_revealed = True + self.disp.display_tunnel(tunnel) + self.disp.display_frame() + + self.inp.wait_on_any_key() # wait on any key + self.move_to_next_step(tunnel, level) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..1adeaea --- /dev/null +++ b/main.py @@ -0,0 +1,102 @@ +import curses +from curses import wrapper +from enum import Enum +from time import sleep + +from enemy import KnifeRat +from input import Input +from level import Level, level_lib +from display import Display +from level_runner import LevelRunner +from player_stats import PlayerStats +from tunnel import Tunnel +from tutorial import tutorial + + +class App: + def __init__(self, scr): + self.disp = Display(scr) + self.inp = Input(scr) + + + def app(self): + selected_item = 0 + menu_items = ["play", "tutorial", "quit"] + while True: + self.disp.new_frame() + self.disp.display_menu_art() + self.disp.display_menu(menu_items, selected_item) + self.disp.display_frame() + + key = self.inp.wait_on_any_key() + if key == curses.KEY_UP or key == ord("w"): + selected_item -= 1 + if selected_item < 0: + selected_item = len(menu_items)-1 + + elif key == curses.KEY_DOWN or key == ord("s"): + selected_item += 1 + if selected_item >= len(menu_items): + selected_item = 0 + + elif key == ord("\n") or key == ord(" "): + match menu_items[selected_item]: + case "play": + self.cycle_through_levels() + case "tutorial": + self.tutorial() + case "quit": + exit(0) + + + def cycle_through_levels(self): + stats = PlayerStats() + level_runner = LevelRunner(self.disp, self.inp, stats) + + level_lib.current_level = 0 + for level in level_lib: + score = level_runner.run_level(level, level_lib.current_level) + if score == 0: + self.defeat_screen() + + self.disp.display_next_level() + self.inp.wait_indefinitely_for_key() + self.inp.wait_indefinitely_for_key() # wait twice to debounce + + self.win_screen() + + def defeat_screen(self): + self.disp.display_lose_screen() + self.inp.wait_indefinitely_for_key() + self.inp.wait_indefinitely_for_key() # wait twice to debounce + + exit(0) + + def win_screen(self): + self.disp.display_win_screen() + self.inp.wait_indefinitely_for_key() + self.inp.wait_indefinitely_for_key() # wait twice to debounce + + exit(0) + + def tutorial(self): + tutorial(self.disp, self.inp) + + + + + + + + + + +if __name__ == '__main__': + def run(scr): + app = App(scr) + app.app() + + wrapper(run) + +# todo fix fizzbuzz +# todo tutorial \ No newline at end of file diff --git a/player_stats.py b/player_stats.py new file mode 100644 index 0000000..cf237ef --- /dev/null +++ b/player_stats.py @@ -0,0 +1,17 @@ + +class PlayerStats: + def __init__(self): + self.lives = 10 + + def lose_life(self): + self.lives -= 1 + + def heal_life(self): + if self.lives < 10: + self.lives += 1 + + def is_dead(self): + if self.lives <= 0: + return True + else: + return False \ No newline at end of file diff --git a/tunnel.py b/tunnel.py new file mode 100644 index 0000000..b5dc506 --- /dev/null +++ b/tunnel.py @@ -0,0 +1,19 @@ +from queue import Queue +from enemy import * + + +class Tunnel: + def __init__(self): + self.next_step = Empty() + self.contents = Queue() + for i in range(15): self.contents.put(Empty()) + print(self.contents.qsize()) + + def append_step(self, step): + self.contents.get() + self.contents.put(self.next_step) + self.next_step = step + + def get_as_str(self) -> str: + result = [i.char for i in self.contents.queue] + return "".join(result) \ No newline at end of file diff --git a/tutorial.py b/tutorial.py new file mode 100644 index 0000000..32be290 --- /dev/null +++ b/tutorial.py @@ -0,0 +1,114 @@ +from time import sleep + +from enemy import Goblin, Empty +from level import level_lib +from level_runner import LevelRunner +from player_stats import PlayerStats +from tunnel import Tunnel + + +def tutorial(disp, inp): + tunnel = Tunnel() + + disp.new_frame() + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(4, 17, "^ this is you") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(2, 18, "v its dark, you cant see whats infront of you") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(2, 18, "v hit space to reveal the next step") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.darkness_revealed = True + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(2, 18, "v hit space again to move forwards") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.darkness_revealed = False + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(2, 18, "v this next step has an enemy in it") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(2, 18, "v this enemy is an o, hit that key to handle it") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.darkness_revealed = True + tunnel.append_step(Goblin()) + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(2, 18, "v there we go! hit space to step forward again") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.darkness_revealed = False + tunnel.append_step(Empty()) + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(4, 18, "^ beware that you'll step forward automatically after a second") + disp.scr.addstr(5, 18, " ain't no time for dawdlin' in the tunnels!") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + disp.display_tunnel(tunnel) + disp.scr.addstr(9, 2, "Enter to continue >") + disp.scr.addstr(5, 2, "recognise the pattern, predict the enemies and handle them") + disp.scr.addstr(6, 2, "you'll lose a few lives to start with, but you'll pick it up quickly") + disp.scr.addstr(7, 2, "survive 40 steps to complete a level") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + + disp.new_frame() + level_runner = LevelRunner(disp, inp, PlayerStats()) + level_runner.run_level(level_lib.get_level(0), 0) + + disp.new_frame() + disp.scr.addstr(2, 2, "You got this! Go explore the real tunnels now!") + disp.display_frame() + + sleep(0.5) + inp.wait_indefinitely_for_key() + +