Project is available for free download!
Karel C Algorithm Library Fibonacci World Diagram

Karel - column reading


  • The solution uses the Fibonacci sequence pattern.
  •       

    Fibonacci sequence - sample program

    // Used from: https://kurzy.kpi.fei.tuke.sk/zap/lectures/04.html
    /* Author: Ing. Marek Paralic, PhD.
       We miss you in our lectures :)
     */
    
    #include <karel.h>
    
    #define SPEED 100
    
    // declarations
    void putFibNum(void);
    void moveBack(void);
    void copyBeepers(void);
    void copyBeepersSkip1(void);
    
    int main(void){
        turnOn("fibonacci.kw");
        setStepDelay(SPEED);
       
        // initialization: first two Fib numbers, F1 and F2
        loop(2) {
            putBeeper();
            movek();
        }
        while( frontIsClear() ){
            putFibNum();
        }
        putFibNum();
       
        turnOff();
        return 0;
    }
    
    // Karel puts to actual position number of beepers
    // equal to the next number in Fib sequence, FibN
    // before: Karel stands at an empty place and the previous
    //         two positions are equal to FibN-1 and FibN-2
    // after : Karel stands at position next to FibN (to the East)
    void putFibNum(void){
        moveBack();
        copyBeepers();
        moveBack();
        copyBeepersSkip1();
        while( beepersPresent() && frontIsClear() ){
            movek();
        }
    }
    
    // do one step back, but keep the original direction
    void moveBack(void){
        setStepDelay(0);
        turnLeft();
        turnLeft();
        movek();
        turnLeft();
        setStepDelay(SPEED);
        turnLeft();
    }
    
    // Karel copies every beeper from actual position
    // to the next position
    void copyBeepers(void){
        pickBeeper();
        if ( beepersPresent() ) {
            copyBeepers();      // recursive function call
        }
        putBeeper();
        movek();
        putBeeper();
        moveBack();
    }
    
    // Karel copies every beeper from actual position
    // two positions to the East
    void copyBeepersSkip1(void){
        pickBeeper();
        if( beepersPresent() ){
            copyBeepersSkip1(); // recursive function call
        }
        putBeeper();
        movek();
        movek();
        putBeeper();
        moveBack();
        moveBack();
    }
    

    World - fibonacci.kw

    8 2 1 1 E 100
    
  • Program implementation of the subtraction does not use variables, only a series of regular cycles.
  • Functionality:
  • In the cycle, Karel moves the beepre from the top row to the bottom until he reaches a point without beeps and returns as much beepro to the original position as the cycle.
  • In the second issue (fibonacci no longer used), which is subtracted, the situation is the same, but here Robot beepre draws from the bottom line and thus adjusts the result to the correct one (added in the first step, now subscribed).
  • Just delete a portion of the Beepers subscription program from the last line for the addition operation.
  •              Initial Status:
    End Status:

    World 1 - world.kw

    9 5 2 3 E 99
    
    B 3 3 4
    
    B 3 2 1
    
    B 4 3 5
    
    B 4 2 2
    
    B 5 3 6
    
    B 5 2 3
    

    World 2 - world2.kw

    10 10 3 9 E 99
    
    B 4 9 10
    
    B 4 8 9
    
    B 5 9 8
    
    B 5 8 2
    
    B 6 9 9
    
    B 6 8 8
    

    World 3 - world3.kw

    5 5 1 3 E 99
    
    B 2 3 5
    
    B 2 2 3
    
    B 3 3 8
    
    B 3 2 6
    
    B 4 3 9
    
    B 4 2 1
    

    Makefile:

          
    # variables
    CC=gcc
    CFLAGS=-std=c11 -Wall -Werror
    LDLIBS=-lkarel -lcurses
    OUTPUT=$@
    
    # targets
    %: %.c
            $(CC) $(CFLAGS) $@.c $(LDLIBS) -o $(OUTPUT)
          

    Library karel.h:

    #include <karel.h>       // nalinkovanie kniznice karla
    #define SPEED 100              // definicia rychlosti pohybu
    void Switcher(void);
    void turnRight(void);
    void moveBack2x(void);
    void moveBack(void);
    void sub(void);
    void rewriteFirstNum(void);
    void minusSecondNum(void);
    // DEFINUJEME FUNKCIE
    void moveBack2x(void){        // funkcia s dvojitym pohybom dozadu a obratom, vyuzivana pri presune z horneho cisla pri prepise
    	loop(2){
    		turnLeft();
    	}
    	loop(2){
    		movek();
    	}
    	loop(2){
    		turnLeft();
    	}
    }
    
    void moveBack(void){     // funkcia s pohybom dozadu a obratom, vyuzivana pri presune o jedno cislo vyssie pri samotnom odcitani cisla
    	loop(2){
    		turnLeft();
    	}
    	movek();
    	loop(2){
    		turnLeft();
    	}
    }
    
    void Switcher(void){    // funkcia Switcher pre switchovanie medzi 2 funkciami, na druhu funkciu prepne az po korektnom vykonani prvej.
    	moveBack2x();
    	rewriteFirstNum();
    	movek();
    	minusSecondNum();
    }
    
    void rewriteFirstNum(void){  // funkcia prepisu prveho cisla v stlpci, funkcia vyuziva dvojnasobny pohyb dozadu
    	pickBeeper();
    	if(beepersPresent()){   // ak je na pozicii stale beeper, tak zdvihaj
    		rewriteFirstNum();
    	}
    	putBeeper(); // nakoniec na prazdne miesto poloz beeper
    	loop(2){
    		movek();
    	}
    	putBeeper(); //poloz beeper pod mensenca
    	moveBack2x();
    }
    
    void minusSecondNum(void){    //funkcia odcitania druheho cisla v stlpci s vyuzitim jedneho posunu dozadu
    	pickBeeper();
    	if(beepersPresent()){ //zdvihaj beeper, ak je stale na pozicii
    		minusSecondNum();
    	}
    	putBeeper();
    	movek();
    	pickBeeper(); //zober beeper od mensenca, odcitavam
    	moveBack();
    	}
    	void sub(void){ // hlavna funkcia, ktora plni odcitanie, obsahuje podfunkciu Switcher, ktora obsahuje dalsie 2 podfunkcie pre prepis a odcitanie cisla
    	movek();
    	turnRight();
    	loop(2){
    		movek();
    	}
    	Switcher();    //Switcher spusta prepis i odcitanie cisel vramci funkcii
    	loop(2){
    		turnRight();
    	}
    	movek();
    	turnRight();
    }
    
    void turnRight(void){    // funkcia pre otocenie doprava
    	loop(3){
    		turnLeft();
    	}
    }
    
    int main(){ //hlavna funkcia main, v ktorej sa vykonava samotny kod programu
    	turnOn("world.kw"); // spustenie sveta robota
    	setStepDelay(SPEED);    //rychlost krokov definovana SPEED-om --> definovany hore
    	loop(3){        //slucka 3x funkcia sub pre kompletne odcitanie troch stlpcov za sebou
    		sub();
    	}
    	movek();        //zaciatok pohybu do vyslednej  polohy robota
    	turnRight();
    	loop(2){
    		movek();
    	}
    	turnLeft();      //koniec pohybu do vyslednej polohy robota
    	turnOff();    //ukoncenie programu
    	return 0;
    }
    						
    #ifndef _KAREL_H
    #define	_KAREL_H
    
    #include <stdio.h>
    #include <stdbool.h>
    
    
    // loop() macro to replace for()
    #define loop(COUNT) for(size_t __loop_cntr = 0; __loop_cntr < COUNT; __loop_cntr++)
    
    
    // *************************************** Primitives 
    
    /**
     * Moves Karel one step forward
     * If there is wall or Karel is at the border of the world, he will be turned 
     * off automatically.
     */
    void movek();
    
    
    /**
     * Turns Karel 90 degrees left
     */
    void turnLeft();
    
    
    /**
     * Initializes the world of Karel the Robot
     * Function has one parameter, which defines the location of world file. If
     * the file doesn't exist, program will be terminated with error message.
     * @param path location of the world file
     */
    void turnOn(char* path);
    
    
    /**
     * Terminates  Karel's program
     */
    void turnOff();
    
    
    /**
     * Puts beeper at the current world position, if Karol has some
     */
    void putBeeper();
    
    
    /**
     * Picks beeper from current position if there is any and puts it to Karol's bag
     */
    void pickBeeper();
    
    
    // *************************************** Sensors
    
    /**
     * Checks, if there are beepers present at the corner
     * @return true, if there are beepers, false otherwise
     */
    bool beepersPresent();
    
    
    /**
     * Checks, if there are no beepers present at the corner
     * @return true, if there are no beepers, false otherwise
     */
    bool noBeepersPresent();
    
    
    /**
     * Checks, if there are any beepers in the bag
     * @return true, if there are some, false otherwise
     */
    bool beepersInBag();
    
    
    /**
     * Checks, if there are no beepers in the bag
     * @return true, if there are no beepers, false otherwise
     */
    bool noBeepersInBag();
    
    
    /**
     * Checks, if front of Karel is clear to go
     * @return true, if clear, false otherwise
     */
    bool frontIsClear();
    
    
    /**
     * Checks, if the front of Karel is not clear to go
     * @return true if it is not clear, false otherwise
     */
    bool frontIsBlocked();
    
    
    /**
     * Checks, if the corner on the left side of Karel is clear to go
     * @return true if it is clear, false otherwise
     */
    bool leftIsClear();
    
    
    /**
     * Checks, if the corner on the left side of Karel is not clear to go
     * @return true if it is not clear, false otherwise
     */
    bool leftIsBlocked();
    
    
    /**
     * Checks, if the corner on the right side of Karel is clear to go
     * @return true if it is clear, false otherwise
     */
    bool rightIsClear();
    
    
    /**
     * Checks, if the corner on the right side of Karel is not clear to go
     * @return true if it is not clear, false otherwise
     */
    bool rightIsBlocked();
    
    
    /**
     * Checks, if Karel is facing north
     * @return true, if yes, false otherwise
     */
    bool facingNorth();
    
    
    /**
     * Checks, if Karel is not facing north
     * @return true, if yes, false otherwise
     */
    bool notFacingNorth();
    
    
    /**
     * Checks, if Karel is facing east
     * @return true, if yes, false otherwise
     */
    bool facingEast();
    
    
    /**
     * Checks, if Karel is not facing east
     * @return true, if yes, false otherwise
     */
    bool notFacingEast();
    
    
    /**
     * Checks, if Karel is facing west
     * @return true, if yes, false otherwise
     */
    bool facingWest();
    
    
    /**
     * Checks, if Karel is not facing west
     * @return true, if yes, false otherwise
     */
    bool notFacingWest();
    
    
    /**
     * Checks, if Karel is facing south
     * @return true, if yes, false otherwise
     */
    bool facingSouth();
    
    
    /**
     * Checks, if Karel is not facing south
     * @return true, if yes, false otherwise
     */
    bool notFacingSouth();
    
    
    // *************************************** Functions
    
    /**
     * Sets the delay of one step
     * @param delay the delay in millis
     */
    void setStepDelay(int delay);
    
    
    /**
     * Returns the current value of Karel's step delay
     * @return the step delay value in millis
     */
    int getStepDelay();
    
    #endif	/* _KAREL_H */
    

    Knižnica internals.h:

    #include "karel.h"
    
    #ifndef _INTERNALS_H
    #define	_INTERNALS_H
    
    
    #define MULTIPLIER 1000
    #define MAX_WIDTH   30
    #define MAX_HEIGHT  30
    
    // global variables (application context)
    extern int stepDelay;
    extern bool summary_mode;
    extern struct world world;
    extern struct robot karel;
    
    enum block{
        CLEAR = 0,
        WALL = -1
    };
    
    
    /**
     * World definition
     */
    struct world{
        int width, height;  // world's width and height
        int **data;         // world data definition
    };
    
    
    /**
     * Available directions
     */
    enum direction{
        EAST = 0,
        NORTH = 90,
        WEST = 180,
        SOUTH = 270
    };
    
    
    /**
     * Robot definition
     */
    struct robot{
        int x, y;       // position
        enum direction direction;   // direction
        int steps;      // nr. of steps
        int beepers;    // nr. of beepers in bag
        bool isRunning; // robot's state
        char lastCommand[10];   // last executed command
    };
    
    
    enum Colors {
        RED_ON_BLACK = 1,
        YELLOW_ON_BLACK,
        WHITE_ON_BLACK
    };
    
    
    /**
     * Draws scene only
     * Draws only world, without karel and state info
     */
    void drawWorld(struct world world, struct robot karel);
    
    
    void render(struct world world, struct robot karel);
    void update(struct world world, struct robot karel, int dx, int dy);
    void errorShutOff(char* message);
    void initialize();
    void deinit();
    
    /**
     * Exports data about world and karel
     * Export is useful in summary mode only. Summary mode can be enabled 
     * with environment variable LIBKAREL_SUMMARY_MODE with it's value "true".
     * @param struct world world data
     * @param struct robot robot karel
     */
    void export_data(struct world world, struct robot karel);
    
    
    #endif	/* _INTERNALS_H */