⚠️ Warning: This is a draft ⚠️

This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.

If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.

{{collection|Hunt_The_Wumpus}}

Ruby


NOTHING = 0; WUMPUS = 1; BAT = 2; PIT = 4; PLAYER = 8; FINISH = 1
PLAY_NEW = 2; PLAY_SAME = 4; S_PLAYER = 0;  MAX_ARROWS = 5; S_WUMPUS = 1
S_BAT1 = 2; S_BAT2 = 3; S_PIT1 = 4; S_PIT2 = 5; MAX_ROOMS = 20; SAVED = 6
MAX_EXITS = 3; A_PATH_LEN = 5
class Room
    attr_reader :obj
    @obj; @exit
    def initialize()
        @obj = NOTHING
        @exit = Array.new(MAX_EXITS) 
    end
    def get_exit(i)
        return @exit[i]
    end
    def clear(obj)
        @obj -= obj
        if @obj < NOTHING then @obj = NOTHING end
    end
    def empty()
        @obj = NOTHING
    end
    def set_exit(i, e)
        @exit[i] = e
    end
    def set_object(obj)
        @obj = @obj + obj
    end
end
class Cave
    @rooms
    def initialize()
        @rooms = Array.new(MAX_ROOMS)
        exits = [1, 4, 7, 0, 2, 9, 1, 3, 11, 2, 4, 13, 0, 3, 5, 4, 6, 14, 5, 7,
                 16, 0, 6, 8, 7, 9, 17, 1, 8, 10, 9, 11, 18, 2, 10, 12, 11, 13, 
                 19, 3, 12, 14, 5, 13, 15, 14, 16, 19, 6, 15, 17, 8, 16, 18, 
                 10, 17, 19, 12, 15, 18]
        for i in 0..@rooms.length
            @rooms[i] = Room.new()
            r = i * MAX_EXITS; a = 0
            for e in r..(r + (MAX_ROOMS - 1))
                @rooms[i].set_exit(a, exits[e])
                a += 1
            end
        end
    end
    def clear_all_rooms()
        @rooms.each do |room|
            room.empty()
        end
    end
    def room(i)
        return @rooms[i]
    end
end
class Game
    @cave; @player; @wumpus; @arrows; @exits; @path; @saved; 
    @gameOver; @playerWins; @game_res
    
    def initialize()
        @player = MAX_ROOMS; @game_res = PLAY_NEW
        @exits = Array.new(MAX_EXITS); @path = Array.new(A_PATH_LEN);
        @saved = Array.new(SAVED); @cave = Cave.new()
        instructions()
    end
    def look()
        room = @cave.room(@player)
        puts "\n-----------------------------------"
        puts "You are in room ##{@player + 1}"
        print "Tunnels lead to rooms #: "
        
        @exits.each do |x|
            print "#{1 + x} " 
        end
        look_around()
    end
    def shoot(pathLen)
        room = @cave.room(@player)
        @path.each do |x|
            if exits(x)
                r = @cave.room(x)
            else 
                r = @cave.room(room.get_exit(rand(MAX_EXITS)))
             end
            obj = r.obj
            if ((WUMPUS & obj) == WUMPUS) 
                 @gameOver = true; @playerWins = true
                return
            end 
            if ((PLAYER & obj) == PLAYER) 
                @gameOver = true; @playerWins = false
                puts "  OUCH! Arrow got you!\n"
                return
            end
        end
        puts "  Missed!\n"; @arrows -= 1
        if @arrows == 0
            iputs "  You run out of arrows...\n"
            @gameOver = true; @playerWins = false
            return
        end
        wumpus(@player)
    end
    def result()
        if @playerWins
            puts "\n  AHA! You got the Wumpus!\n  HEE HEE HEE - " <<
            "The Wumpus'll getcha next time!!\n\n"
        else 
            puts "  HA HA HA - You lose!\n\n"
        end
        print "\nPlay again (Y/N)? "; i = gets[0].downcase
        if i == "y"
            print "Same setup (Y/N)? "; i = gets[0].downcase
            if i == "y" 
                return PLAY_SAME
            else
                return PLAY_NEW
            end
        end
        return FINISH
    end
    def look_around()
        msg = 0
        @exits.each do |x|
            obj = @cave.room(x).obj
            if ((WUMPUS & obj) == WUMPUS) then msg += WUMPUS end
            if ((BAT & obj) == BAT) then msg += BAT end
            if ((PIT & obj) == PIT) then msg += PIT end
        end
        puts "\n"
        if ((msg & WUMPUS) == WUMPUS) 
            puts "- You smell something terrible nearby." 
        end
        if ((msg & PIT) == PIT) 
            puts "- You feel a cold wind blowing from a nearby cavern." 
        end
        if ((msg & BAT) == BAT)
            puts "- You hear a rustling." 
        end
    end
    def exits(e)
        @exits.each do |x|
            return true if e == x
        end
        return false
    end
    def input()
        print "\nShoot or Move (S/M)? "; r = gets[0].downcase
        case r
            when "o"
                puts @cave.room(@player).obj
            when "m"
                print "Where to? "; ex = gets.to_i
                return false if ex == nil or ex < 0 or ex > MAX_ROOMS + 1
                ex -= 1
                if exits(ex)
                    set_player(ex)
                else 
                    puts "\nArrggh! --- You cannot go there!\n\n"
                end
                return true
            when "s"
                  pathLen = 0
                loop do
                    print "\nNumber of rooms (1-5)? "
                      pathLen = gets.to_i
                      break if pathLen > 0 and pathLen < (A_PATH_LEN + 1)
                end
                cnt = 0
                loop do
                    print "Room #"; n = gets.to_i
                    if n != nil and n > 0 and n < (MAX_ROOMS + 1)
                        @path[cnt] = n - 1
                        if cnt < 2 or @path[cnt] != @path[cnt - 2]
                            cnt += 1
                        else
                            puts "\nArrows aren't that crooked! - " <<
                            "Please, try another room.\n\n"
                        end
                    end
                    break if cnt == pathLen
                end
                shoot(pathLen)
                return true
        end
        return false
    end
    def set_player(pos)
        @cave.room(@player).clear(PLAYER) if @player < MAX_ROOMS 
        return if hazards(pos) 
        @player = pos
        room = @cave.room(@player)
        room.set_object(PLAYER)
        for i in 0..(MAX_EXITS - 1)
            @exits[i] = room.get_exit(i)
        end
    end
    def hazards(pos)
        room = @cave.room(pos); obj = room.obj
        if ((WUMPUS & obj) == WUMPUS)
            puts "\n  ...OOPS! Bumped a Wumpus!\n\n"
            if wumpus(pos)
                puts "\n  TSK TSK TSK - Wumpus got you!\n"
                @gameOver = true; @playerWins = false
                return true
            end
        end
        if ((PIT & obj) == PIT)
            puts "\n  YYYYIIIIEEEE!!!! Fell in pit!\n"
            @gameOver = true; @playerWins = false
            return true
        end
        if ((BAT & obj) == BAT)
            puts "\n  ZAP -- Super bat snatch! Elsewhereville for you!\n\n"
            set_player(rand(MAX_ROOMS))
            return true;
        end
        return false
    end
    def wumpus(pos)
        if rand(100) < 75 
            room = @cave.room(@wumpus)
            room.clear(WUMPUS)
            @wumpus = room.get_exit(rand(MAX_EXITS))
            @cave.room(@wumpus).set_object(WUMPUS)
        end
        return pos == @wumpus
    end
    def init()
        puts "\n\n\n\nHUNT THE WUMPUS\n---------------\n"
        @cave.clear_all_rooms(); @gameOver = false; @arrows = MAX_ARROWS
        if @game_res == PLAY_NEW
            @saved[S_PLAYER] = rand(MAX_ROOMS); set_player(@saved[S_PLAYER])
            @saved[S_BAT1] = fill_room(BAT); @saved[S_BAT2] = fill_room(BAT)
            @saved[S_PIT1] = fill_room(PIT); @saved[S_PIT2] = fill_room(PIT)
            @wumpus = @saved[S_WUMPUS] = fill_room(WUMPUS)
        else
            set_player(@saved[S_PLAYER]); @wumpus = @saved[S_WUMPUS]
            @cave.room(@wumpus).set_object(WUMPUS)
            @cave.room(@saved[S_BAT1]).set_object(BAT)
            @cave.room(@saved[S_BAT2]).set_object(BAT)
            @cave.room(@saved[S_PIT1]).set_object(PIT)
            @cave.room(@saved[S_PIT2]).set_object(PIT)
        end
    end
    def fill_room(obj)
        i = 0; room = nil
        loop do
            i = rand(MAX_ROOMS)
            room = @cave.room(i)
            break if room.obj == NOTHING
         end
        room.set_object(obj)
        return i
    end
    def instructions()
        print "\n\nWelcome to 'HUNT THE WUMPUS'\n\nInstructions (Y/N)? "; 
        return if gets.chomp.downcase == 'n'
        puts "\n\nThe Wumpus lives in a cave of 20 rooms: each room has 3 " <<
             "tunnels leading to other rooms.\n(Look at a Dodecahedron to " <<
             "see how this works, if you don't know what a dodecahedron is," <<
             " ask someone)\n\nHAZARDS:\n--------\n\nBottomless pits:\n" <<
             "----------------\nTwo rooms have bottomless pits in them " <<
             "- if you go there, you fall into the pit and lose!\n\nSuper" <<
             "bats:\n-----------\nTwo other rooms have super bats - if " <<
             "you go there, a bat grabs you and takes you to some other" << 
             " room at random,\nwhich might be troublesome.\n\nWumpus:\n-" <<
             "------\nThe Wumpus is not bothered by the hazards, he has " <<
             "sucker feet and is too big for a bat to lift. Usually he is " <<
             "asleep.\nTwo things wake him up: your entering his room or" <<
             " your shooting an arrow.\nIf the Wumpus wakes, he has 75% " <<
             "chance to move one room or 25% chance to stay still.\nAfter" <<
             " that, if he is where you are, he eats you up and you lose!" <<
             "\n\nYou:\n----\nEach turn you may move or shoot a crooked " <<
             "arrow.\n- Moving: you can move one room (thru one tunnel)" <<
             "\n- Arrows: you have 5 arrows. You lose when you run out.\n" <<
             "  Each arrow can go from 1 to 5 rooms, you aim by telling " << 
             "the computer the  rooms #s you want the arrow to go to.\n" <<
             "  If the arrow can't go that way (if no tunnel) it moves at" <<
             " random to the \n  next room.\n  If the arrow hits the " <<
             "Wumpus: you win, if the arrow hits you: you lose.\n \n\n" <<
             "WARNINGS:\n--------\nWhen you are one room away from " <<
             "Wumpus or any other hazard, the computer says:\nWumpus:" <<
             " 'You smell something terrible nearby.'\nBat: 'You hear" <<
             " a rustling.'\nPit: 'You feel a cold wind blowing from" <<
             " a nearby cavern.'\n\n\nPress return to play..."
        gets   
    end
    def main_loop()
        while @game_res != FINISH
            init()
            while not @gameOver 
                look()
                begin
                    i = input()
                end while not i
            end
            @game_res = result();
        end
    end
end
@game = Game.new().main_loop()