Elevator simulation

From Rosetta Code
Revision as of 15:04, 24 August 2021 by Nigel Galloway (talk | contribs)
Elevator simulation is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task


To see how it works watch the next video
Evelator Game in Ring - video
Necessary image files - download
Please if you can attach a video file how your sample works.

Reference
The Elevator Game — What To Know And Why You Shouldn’t Play

Br>

Ring


Evelator Game in Ring - video

<lang ring>

  1. Project : Elevator Game
  2. Date  : 21/08/2021-02:26:57
  3. Author  : Gal Zsolt (~ CalmoSoft ~)
  4. Email  : calmosoft@gmail.com

load "stdlib.ring" load "guilib.ring"

floorCount = 7 randEvelator = 1 randWait = 1 randOld = 0 nFloor = 0 count = 0 flag = 0 targetFloor = 0 floor = list(floorCount) floorbtn = list(floorCount) floorCall = list(floorCount) C_UP = "images/up.jpg" C_DOWN = "images/down.jpg" C_WAIT = "images/wait.jpg" C_EMPTY = "images/empty.jpg" C_OPEN = "images/elevatoropen.jpg" C_CLOSE = "images/elevatorclose.jpg" C_CLOSEELEVATOR = "images/closeevelator.jpg" C_RECTANGLE = "images/rectangle.jpg" floorbtn[1] = "images/floor0.jpg" floorbtn[2] = "images/floor1.jpg" floorbtn[3] = "images/floor2.jpg" floorbtn[4] = "images/floor3.jpg" floorbtn[5] = "images/floor4.jpg" floorbtn[6] = "images/floor5.jpg" floorbtn[7] = "images/floor6.jpg"

oFont = new qfont("Verdana",16,0,0) C_ButtonOrangeStyle = 'border-radius:6px;color:black; background-color: orange'

app = new qApp {

     stylefusionblack()
     processevents()
     win = new qWidget() {

setWindowTitle('Elevator Game')

           setWindowIcon(new qIcon(new qPixmap(C_OPEN)))

move(550,140) reSize(800,700)

           app.processEvents()
           for n = 1 to floorCount

floor[n] = new QPushButton(win) { setgeometry(150,510-(n-2)*90,85,85) }

           next
           showFloor = new QPushButton(win)	

{ setgeometry(150,15,90,25) setstylesheet(C_ButtonOrangestyle)

                         setfont(oFont)
                       }

rectangle = new QPushButton(win) { setgeometry(330,55,100,180) setstylesheet(C_ButtonOrangestyle)

                         setIconSize(new qSize(66,66))
                       }

down = new QPushButton(win) { setgeometry(350,150,66,66)

                    setfont(oFont)

seticon(new qicon(new qpixmap(C_DOWN)))

                    setIconSize(new qSize(66,66))
                    setclickevent("pMoveDown()")
                  }

up = new QPushButton(win) { setgeometry(350,70,66,66)

                  setfont(oFont)

seticon(new qicon(new qpixmap(C_UP)))

                  setIconSize(new qSize(66,66))
                  setclickevent("pMoveUp()")
                }

newGame = new QPushButton(win) { setgeometry(550,300,150,50) setstylesheet(C_ButtonOrangestyle)

                       setfont(oFont)
                       settext("New Game")
                       setclickevent("pNewGame()")
                     }

exitButton = new QPushButton(win) { setgeometry(550,500,150,50) setstylesheet(C_ButtonOrangestyle)

                          setfont(oFont)
                          setClickEvent("pExit()")

settext("Exit") }

rectangleFloor = new QPushButton(win) { setgeometry(280,260,190,420) setstylesheet(C_ButtonOrangestyle)

                              setIconSize(new qSize(66,66))
                            }

floorCall[1] = new QPushButton(win) { setgeometry(343,506,66,66) seticon(new qicon(new qpixmap(floorbtn[1])))

                            setIconSize(new qSize(100,100))
                            settext("GF")
                            setclickevent("pMove(" + "1" + ")")
                          }

floorCall[2] = new QPushButton(win) { setgeometry(300,420,66,66) seticon(new qicon(new qpixmap(floorbtn[2])))

                            setIconSize(new qSize(100,100))
                            setclickevent("pMove(" + "2" + ")")
                          }

floorCall[3] = new QPushButton(win) { setgeometry(386,420,66,66) seticon(new qicon(new qpixmap(floorbtn[3])))

                            setIconSize(new qSize(100,100))
                            setclickevent("pMove(" + "3" + ")")
                          }

floorCall[4] = new QPushButton(win) { setgeometry(300,344,66,66) seticon(new qicon(new qpixmap(floorbtn[4])))

                            setIconSize(new qSize(100,100))
                            setclickevent("pMove(" + "4" + ")")
                            show()	
                          }

floorCall[5] = new QPushButton(win) { setgeometry(386,344,66,66) seticon(new qicon(new qpixmap(floorbtn[5])))

                            setIconSize(new qSize(100,100))
                            setclickevent("pMove(" + "5" + ")")
                            show()	
                          }

floorCall[6] = new QPushButton(win) { setgeometry(300,268,66,66) seticon(new qicon(new qpixmap(floorbtn[6])))

                            setIconSize(new qSize(100,100))
                            setclickevent("pMove(" + "6" + ")")
                          }

floorCall[7] = new QPushButton(win) { setgeometry(386,268,66,66) seticon(new qicon(new qpixmap(floorbtn[7])))

                            setIconSize(new qSize(100,100))
                            setclickevent("pMove(" + "7" + ")")
                          }

close = new QPushButton(win) { setgeometry(340,592,66,66) seticon(new qicon(new qpixmap(C_CLOSEELEVATOR)))

                     setIconSize(new qSize(66,66))
                     setclickevent("pClose()")
                   }        
           show()
     }
     pBegin()
     exec()   

}

func pNewGame()

    pBegin()
    pWait()

func pBegin()

    flag = 0
    count = 0
    for n = 1 to floorCount

floor[n] { seticon(new qicon(new qpixmap(C_EMPTY)))

                   setIconSize(new qSize(100,100)) }	
    next
    randEvelator = random(floorCount-1) + 1
    for n = 1 to floorCount

floorCall[n] { setenabled(False) }

    next
    up { setenabled(True) }
    down { setenabled(True) }
    pWait()

func pWait()

    floor[randWait] { seticon(new qicon(new qpixmap(C_EMPTY)))
                      setIconSize(new qSize(100,100)) }
    randWait = random(floorCount-1) + 1
    while true 
          if randWait != randEvelator
             nFloor = randEvelator
             floor[randWait] { seticon(new qicon(new qpixmap(C_WAIT)))
                               setIconSize(new qSize(100,100)) }
             floor[randEvelator] { seticon(new qicon(new qpixmap(C_CLOSE)))
                                   setIconSize(new qSize(100,100)) }
             showFloor.settext(string(randEvelator-1))
             for n = 1 to floorCount
                 floorCall[n] { setenabled(False) }
             next
             exit
          else
             randEvelator = random(floorCount-1) + 1
          ok
    end
    return

func pMove(sourceFloor)

    if flag = 1
    n = 0
    pClose()
    app.processEvents()
    sleep(0.5)
    up { setenabled(false) }
    down { setenabled(false) }
    count = count + 1
    if count = 1
       targetFloor = randWait
    else
       targetFloor = randOld
    ok
    n = 0
    if sourceFloor > targetFloor
       for n = targetFloor to sourceFloor - 1
           app.processEvents()
           sleep(0.5)
           floor[n] { seticon(new qicon(new qpixmap(C_EMPTY)))
                      setIconSize(new qSize(100,100)) }
           floor[n+1] { seticon(new qicon(new qpixmap(C_CLOSE)))
                      setIconSize(new qSize(100,100)) }
           if n = 0
              showFloor.settext("GF")
           else
              showFloor.settext(string(n))
           ok
           if n = sourceFloor - 1
              nFloor = n + 1
              floor[n+1] { seticon(new qicon(new qpixmap(C_OPEN)))
                           setIconSize(new qSize(100,100)) }
           ok
       next
       see nl
    ok
    n = 0
    if sourceFloor < targetFloor 
       for n = targetFloor to sourceFloor + 1 step -1
           app.processEvents()
           sleep(0.5)
           floor[n] { seticon(new qicon(new qpixmap(C_EMPTY)))
                      setIconSize(new qSize(100,100)) }
           floor[n-1] { seticon(new qicon(new qpixmap(C_CLOSE)))
                        setIconSize(new qSize(100,100)) }
           if n = 2
              showFloor.settext("GF")
           else
              showFloor.settext(string(n-2))
           ok
           if n = sourceFloor + 1
              nFloor = n - 1
              floor[n-1] { seticon(new qicon(new qpixmap(C_OPEN)))
                           setIconSize(new qSize(100,100)) }
           ok
       next
       see nl
    ok
    randOld = sourceFloor
    ok

func pMoveDown

    if randWait > randEvelator
       return
    ok
    for n = 1 to floorCount

floorCall[n] { setenabled(True) }

    next
    if randWait < randEvelator
       for n = randEvelator to randWait + 1 step -1
           app.processEvents()
           sleep(0.5)
           floor[n] { seticon(new qicon(new qpixmap(C_EMPTY)))
                      setIconSize(new qSize(100,100)) }
           floor[n-1] { seticon(new qicon(new qpixmap(C_CLOSE)))
                        setIconSize(new qSize(100,100)) }
           if n = 0
              showFloor.settext("GF")
           else
              showFloor.settext(string(n-2))
           ok
           if n = randWait + 1
                  nFloor = n - 1
                  floor[n-1] { seticon(new qicon(new qpixmap(C_OPEN)))
                               setIconSize(new qSize(100,100)) }
           ok
       next
    ok 
    app.processEvents()
    sleep(1)
    flag++       

func pMoveUp()

    if randWait < randEvelator
       return
    ok    
    for n = 1 to floorCount

floorCall[n] { setenabled(True) }

    next
    if randWait > randEvelator
       for n = randEvelator to randWait - 1
           app.processEvents()
           sleep(0.5)
           floor[n] { seticon(new qicon(new qpixmap(C_EMPTY)))
                      setIconSize(new qSize(100,100)) }
           floor[n+1] { seticon(new qicon(new qpixmap(C_CLOSE)))
                        setIconSize(new qSize(100,100)) }
           if n = 1
              showFloor.settext("GF")
           else
              showFloor.settext(string(n))
           ok
           if n = randWait - 1
                  nFloor = n + 1
                  floor[n+1] { seticon(new qicon(new qpixmap(C_OPEN)))
                               setIconSize(new qSize(100,100)) }
           ok
        next
    ok   
    app.processEvents()
    sleep(1)
    flag++

func pClose()

    floor[nFloor] { seticon(new qicon(new qpixmap(C_CLOSE)))
                    setIconSize(new qSize(100,100)) } 

func pExit()

    win.close()
    app.quit()

</lang>

Wren

Library: DOME
Library: Wren-dynamic
Library: Wren-ellipse
Library: Go-fonts

It's not currently possible to run a DOME application online in a browser but the following is designed to look and work more or less like the Ring entry. However, the user interface is not as fancy as I don't have ready made images of elevators etc. available. <lang ecmascript>import "dome" for Window, Platform, Process import "graphics" for Canvas, Color, Font import "audio" for AudioEngine import "input" for Mouse import "random" for Random import "./dynamic" for Enum import "./ellipse" for Circle, Polygon, Rectangle, Square

var Direction = Enum.create("Direction", ["halted", "up", "down"])

var Rand = Random.new()

class Elevator {

   construct new() {
       Window.resize(820, 820)
       Canvas.resize(820, 820)
       Window.title = "Elevator game"
       // see Go-fonts page
       Font.load("Go-Regular20", "Go-Regular.ttf", 20)
       Canvas.font = "Go-Regular20"
       Font.load("Go-Regular25", "Go-Regular.ttf", 25)
       // download from https://soundbible.com/509-Mouse-Double-Click.html
       AudioEngine.load("click", "mouse_click.wav")        
   }
   init() {
       newGame()
   }
   newGame() {
       _buttons = []
       // floors
       for (i in 1..7) {
           Canvas.rectfill(120, 100*i + 5, 90, 90, Color.white)
       }
       // floor up/down buttons
       Canvas.rectfill(300, 30, 100, 200, Color.orange)
       var up = Square.new(315, 45, 70, "up")
       up.drawfill(Color.lightgray)
       _buttons.add(up)
       Canvas.print("\u25b2", 345, 70, Color.black)
       var down = Square.new(315, 145, 70, "down")
       down.drawfill(Color.lightgray)
       _buttons.add(down)
       Canvas.print("\u25bc", 345, 170, Color.black)
       // floor number buttons
       Canvas.rectfill(250, 305, 200, 490, Color.orange)
       var f25 = "Go-Regular25"
       var floor5 = Circle.new(300, 350, 40, 5)
       floor5.drawfill(Color.lightgray)
       Canvas.print("5", 295, 340, Color.black, f25) 
       var floor6 = Circle.new(400, 350, 40, 6)
       floor6.drawfill(Color.lightgray)
       Canvas.print("6", 395, 340, Color.black, f25)
       var floor3 = Circle.new(300, 450, 40, 3)
       floor3.drawfill(Color.lightgray)
       Canvas.print("3", 295, 440, Color.black, f25) 
       var floor4 = Circle.new(400, 450, 40, 4)
       floor4.drawfill(Color.lightgray)
       Canvas.print("4", 395, 440, Color.black, f25) 
       var floor1 = Circle.new(300, 550, 40, 1)
       floor1.drawfill(Color.lightgray)
       Canvas.print("1", 295, 540, Color.black, f25)
       var floor2 = Circle.new(400, 550, 40, 2)
       floor2.drawfill(Color.lightgray)
       Canvas.print("2", 395, 540, Color.black, f25)
       var ground = Square.fromCenter(350, 650, 80, "ground")
       ground.drawfill(Color.white)
       Canvas.print("GF", 335, 640, Color.black, f25)
       var close = Square.fromCenter(350, 750, 80, "close")
       close.drawfill(Color.white, Color.black, 2)
       Canvas.print("\u25ba\u25c4", 330, 740, Color.black)
       _buttons.addAll([floor1, floor2, floor3, floor4, floor5, floor6, ground, close])
       // new game button
       var newGame = Rectangle.new(525, 355, 150, 50, "new")
       newGame.drawfill(Color.orange)
       Canvas.print("New Game", 545, 365, Color.black)
       _buttons.add(newGame)
       // exit button
       var exit = Rectangle.new(525, 595, 150, 50, "exit")
       exit.drawfill(Color.orange)
       Canvas.print("Exit", 575, 605, Color.black)
       _buttons.add(exit)
   
       _floor = Rand.int(0, 7) // start by placing lift on a random floor
       drawLift()
       openDoors()
       changeFloorNumber()
       _dir = Direction.halted
       _floorDest = _floor
       _start = 0
       _wait = Rand.int(0, 7)  // start with a random wait point, different to where lift is
       if (_wait == _floor) {
           _wait = _floor - 1
           if (_wait < 0) _wait = 2
       }
       var wait = Polygon.regular(4, 165, 750 - _wait*100, 45, 0)
       wait.drawfill(Color.yellow, Color.black)
       Canvas.print("WAIT", 140, 740 - _wait*100, Color.black)
   }
   update() {
       if (Mouse["left"].justPressed) {
           var x = Mouse.x
           var y = Mouse.y
           for (btn in _buttons) {
               if (btn.contains(x, y)) {
                   var t = btn.tag
                   if (t == "up") {
                       if (_floor < 6) {
                           _dir = Direction.up
                           _floorDest = 6
                       }
                   } else if (t == "down") {
                       if (_floor > 0) {
                           _dir = Direction.down
                           _floorDest = 0
                       }
                   } else if (t is Num) {
                        if (t < _floor) {
                           _dir = Direction.down
                        } else if (t > _floor) {
                           _dir = Direction.up
                        } else {
                           _dir = Direction.halted
                           openDoors()
                        }
                        _floorDest = t
                   } else if (t == "ground") {
                        if (_floor > 0) {
                           _dir = Direction.down
                        } else {
                           _dir = Direction.halted
                           openDoors()
                        }
                        _floorDest = 0
                   } else if (t == "close") {
                        if (_dir == Direction.halted) {
                           closeDoors()
                        }
                   } else if (t == "new") {
                       Canvas.cls("black")
                       newGame()
                   } else if (t == "exit") {
                       Process.exit()
                   }
                   if (_dir != Direction.halted) {
                       closeDoors()
                       _start = Platform.time
                   } else {
                       _start = 0
                   }
               }
           }
       }
   }
   drawLift() {
       Canvas.rectfill(120, 100*(7 - _floor) + 5, 90, 90, Color.blue)
   }
   undrawLift() {
       Canvas.rectfill(120, 100*(7 - _floor) + 5, 90, 90, Color.white)
   }
   changeFloorNumber() {
       Canvas.rectfill(120, 30, 90, 40, Color.orange)
       Canvas.print(_floor.toString, 160, 40, Color.black)
   }
   openDoors() {
       Canvas.rectfill(135, 100*(7 - _floor) + 30, 60, 60, Color.white)
   }
   closeDoors() {
       Canvas.rectfill(120, 100*(7 - _floor) + 5, 90, 90, Color.blue)
   }
       
   draw(alpha) {
       if (_start > 0) {
           var delta = Platform.time - _start
           if (delta >= 1) {
               undrawLift()
               _floor = (_dir == Direction.up) ? _floor + 1 : _floor - 1
               drawLift()
               changeFloorNumber()
               if (_floor == _wait) {
                   _dir = Direction.halted
                   _start = 0
                   _wait = -1
                   openDoors()
               } else if (_floor == _floorDest) {
                   _dir = Direction.halted
                   _start = 0
                   openDoors()        
               } else {
                   _start = _start + delta
               }
           }
       }
   }

}

var Game = Elevator.new()</lang>