Week 5 Code Examples

// COMP1511 Week 5 Lecture 
// Time to get our hands (or paws) dirty and write a larger lecture program
// Angela Finlayson 

#include <stdio.h>

// Provided Constants
#define INVALID_INDEX -1
#define MAP_ROWS 8
#define MAP_COLS 8
#define MAX_MUD_STEPS 3


// User define constants go here
#define UP 'w'
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'

// Provided enums and structs
enum ground_type {
    GRASS,
    MUD
};

enum item_type {
    EMPTY,
    BONE
};

struct location {
    enum item_type item;
    enum ground_type ground;
};

// User defined enums and structs
struct dog {
    int row;
    int col;
    int bone_count;
    int mud_count;
};
 
// Provided function prototypes
void initialise_map(struct location map[MAP_ROWS][MAP_COLS]);

void print_map(
    struct location map[MAP_ROWS][MAP_COLS], 
    int dog_row, 
    int dog_col,
    int bone_count,
    int mud_count
);

void print_location(struct location location, int ground_layer, int print_dog);
void print_ground_type(enum ground_type ground);
void print_item_type(enum item_type item);

// User defined function prototypes
int is_valid_location(int row, int col);
struct dog process_move(
    struct location map[MAP_ROWS][MAP_COLS],
    struct dog dog
);

void find_bones(
    struct location map[MAP_ROWS][MAP_COLS],
    struct dog dog
);

int main(void) {
    struct location map[MAP_ROWS][MAP_COLS];
    initialise_map(map);
    print_map(map, INVALID_INDEX, INVALID_INDEX, 0, 0);
    
    struct dog dog;
    dog.bone_count = 0;
    dog.mud_count = 0;

    printf("Enter dog's location: "); 
    scanf("%d %d", &dog.row, &dog.col);
    if (is_valid_location(dog.row, dog.col) == 0) {
        dog.row = 0;
        dog.col = 0;
    }

    dog = process_move(map, dog);    

    print_map(map, dog.row, dog.col, dog.bone_count, dog.mud_count);
    printf("\nLet's find some bones, but watch the mud!!!!\n");
    find_bones(map, dog);

    printf("Woof Woof\n");
    return 0;
}

// returns 1 if the row and col are legal indexes
// return 0 otherwise
int is_valid_location(int row, int col) {
    int valid = 1;
    if (row < 0 || row >= MAP_ROWS ||
        col < 0 || col >= MAP_COLS) {
        valid = 0;
    } 
    return valid;
}

struct dog process_move(
    struct location map[MAP_ROWS][MAP_COLS],
    struct dog dog
) {
    if (map[dog.row][dog.col].item == BONE) {
        dog.bone_count++;
        map[dog.row][dog.col].item = EMPTY;
    }

    if (map[dog.row][dog.col].ground == MUD) {
        dog.mud_count++;
    }
    return dog;
}

void find_bones(
    struct location map[MAP_ROWS][MAP_COLS],
    struct dog dog
) {
    printf("Enter command: ");
    char command;
    while (scanf(" %c", &command) == 1) {
        if (command == UP) {
            dog.row--;
        } else if (command == DOWN) {
            dog.row++;
        } else if (command == LEFT) {
            dog.col--;
        } else if (command == RIGHT) {
            dog.col++;
        }
        dog = process_move(map, dog);
        print_map(map, dog.row, dog.col, dog.bone_count, dog.mud_count);
        printf("Enter command: ");
    }
}

// STARTER FUNCTIONS BELOW THIS POINT //////////////////////////

// initialises the map with empty items and grass ground types
// Hard codes some bones and mud
void initialise_map(struct location map[MAP_ROWS][MAP_COLS]) {
    int row = 0;
    while (row < MAP_ROWS) {
        int col = 0;
        while (col < MAP_COLS) {
            map[row][col].ground = GRASS;
            map[row][col].item = EMPTY;
            col++;
        }
        row++;
    } 
    // Hard coding these instead of getting user input
    // so I don't give away too much for the assignment
    // and to save time
    map[0][1].item = BONE;
    map[1][1].item = BONE;
    map[7][7].item = BONE;
    map[5][1].item = BONE;
    map[0][1].ground = MUD;
    map[7][6].ground = MUD;
    map[0][2].ground = MUD;
    map[0][3].ground = MUD;
}

// Print out the map and then the game stats
// Each row has 2 lines of output,
// the first line represents the dog or item
// the second line represents the ground
void print_map(
    struct location map[MAP_ROWS][MAP_COLS],
    int dog_row,
    int dog_col,
    int bone_count,
    int mud_count
) {
    printf("========= Mud and Bones =========\n");

    for (int row = 0; row < MAP_ROWS * 2; row++) {
        if (row % 2 == 0) {
            for (int col = 0; col < MAP_COLS; col++) {
                printf("+---");
            }
            printf("+\n");
        }

        for (int col = 0; col < MAP_COLS; col++) {
            int print_dog = 0;
            if (dog_row == row / 2 && dog_col == col) {
                print_dog = 1;
            }

            printf("|");
            print_location(map[row / 2][col], row % 2, print_dog);
        }
        printf("|\n");
    }

    for (int col = 0; col < MAP_COLS; col++) {
        printf("+---");
    }
    printf("+\n");

    printf("Bones: %2d                Mud: %2d\n", 
            bone_count, mud_count);
    printf("=================================\n\n");
}
 

// prints specific location on map (used by print_map)
void print_location(
    struct location location,  int print_ground, int print_dog) {
    if (print_ground) {
        print_ground_type(location.ground);
    } else {
        if (print_dog) {
            printf("🐕 ");
        } else {
            print_item_type(location.item);
        }
    }
}

// Takes a ground type enum as input and prints 
// a corresponding character to visually represent it
void print_ground_type(enum ground_type ground) {
    if (ground == GRASS) {
        printf(" . ");
    } else if (ground == MUD) {
        printf(" M ");
    } else {
        printf(" ? ");
    }
}

// Takes an item type enum as input and prints 
// a corresponding character to visually represent it
void print_item_type(enum item_type item) {
    if (item == EMPTY) {
        printf("   ");
    } else if (item == BONE) {
        printf(" B ");
    } else {
        printf(" ? ");
    }
}
// COMP1511 Week 5 Lecture 
// Time to get our hands (or paws) dirty and write a larger lecture program
// Angela Finlayson 

#include <stdio.h>

// Provided Constants
#define INVALID_INDEX -1
#define MAP_ROWS 8
#define MAP_COLS 8
#define MAX_MUD_STEPS 3


// User define constants go here


// Provided enums and structs
enum ground_type {
    GRASS,
    MUD
};

enum item_type {
    EMPTY,
    BONE
};

struct location {
    enum item_type item;
    enum ground_type ground;
};

// User defined enums and structs

 
// Provided function prototypes
void initialise_map(struct location map[MAP_ROWS][MAP_COLS]);

void print_map(
    struct location map[MAP_ROWS][MAP_COLS], 
    int dog_row, 
    int dog_col,
    int bone_count,
    int mud_count
);

void print_location(struct location location, int ground_layer, int print_dog);
void print_ground_type(enum ground_type ground);
void print_item_type(enum item_type item);

// User defined function prototypes
  

int main(void) {
    struct location map[MAP_ROWS][MAP_COLS];
    initialise_map(map);
    print_map(map, INVALID_INDEX, INVALID_INDEX, 0, 0);
    
    printf("Enter dog's location: "); 
    //TODO

    printf("\nLet's find some bones, but watch the mud!!!!\n");
    //TODO

    printf("Woof Woof\n");
    return 0;
}

// STARTER FUNCTIONS BELOW THIS POINT //////////////////////////

// initialises the map with empty items and grass ground types
// Hard codes some bones and mud
void initialise_map(struct location map[MAP_ROWS][MAP_COLS]) {
    int row = 0;
    while (row < MAP_ROWS) {
        int col = 0;
        while (col < MAP_COLS) {
            map[row][col].ground = GRASS;
            map[row][col].item = EMPTY;
            col++;
        }
        row++;
    } 
    // Hard coding these instead of getting user input
    // so I don't give away too much for the assignment
    // and to save time
    map[0][1].item = BONE;
    map[1][1].item = BONE;
    map[7][7].item = BONE;
    map[5][1].item = BONE;
    map[0][1].ground = MUD;
    map[7][6].ground = MUD;
    map[0][2].ground = MUD;
    map[0][3].ground = MUD;
}

// Print out the map and then the game stats
// Each row has 2 lines of output,
// the first line represents the dog or item
// the second line represents the ground
void print_map(
    struct location map[MAP_ROWS][MAP_COLS],
    int dog_row,
    int dog_col,
    int bone_count,
    int mud_count
) {
    printf("========= Mud and Bones =========\n");

    for (int row = 0; row < MAP_ROWS * 2; row++) {
        if (row % 2 == 0) {
            for (int col = 0; col < MAP_COLS; col++) {
                printf("+---");
            }
            printf("+\n");
        }

        for (int col = 0; col < MAP_COLS; col++) {
            int print_dog = 0;
            if (dog_row == row / 2 && dog_col == col) {
                print_dog = 1;
            }

            printf("|");
            print_location(map[row / 2][col], row % 2, print_dog);
        }
        printf("|\n");
    }

    for (int col = 0; col < MAP_COLS; col++) {
        printf("+---");
    }
    printf("+\n");

    printf("Bones: %2d                Mud: %2d\n", 
            bone_count, mud_count);
    printf("=================================\n\n");
}
 

// prints specific location on map (used by print_map)
void print_location(
    struct location location,  int print_ground, int print_dog) {
    if (print_ground) {
        print_ground_type(location.ground);
    } else {
        if (print_dog) {
            printf("🐕 ");
        } else {
            print_item_type(location.item);
        }
    }
}

// Takes a ground type enum as input and prints 
// a corresponding character to visually represent it
void print_ground_type(enum ground_type ground) {
    if (ground == GRASS) {
        printf(" . ");
    } else if (ground == MUD) {
        printf(" M ");
    } else {
        printf(" ? ");
    }
}

// Takes an item type enum as input and prints 
// a corresponding character to visually represent it
void print_item_type(enum item_type item) {
    if (item == EMPTY) {
        printf("   ");
    } else if (item == BONE) {
        printf(" B ");
    } else {
        printf(" ? ");
    }
}
#include <stdio.h>

int main(void){
    char word[] ="pirate";
    word[2] = '\0';
    printf("%s", word); 
    return 0;
}
#include <stdio.h>

int main(void){
    char word[] ="cat";
    word[3] = 's';
    printf("%s", word); 
    return 0;
}
#include <stdio.h>
#include <string.h>

int main(void){
    char s[] ="I can!";
    int len = strlen(s);
    printf("%d", len); 
    return 0;
}
#include <stdio.h>

int main(void){
    char word[100];
    word ="kfc";
    printf("%s", word); 
    return 0;
}
#include <stdio.h>

int main(void){
    char s[] = "";
    printf("%s", s); 
    return 0;
}
#include <stdio.h>
#include <string.h>

int main(void){
    char word[] = "kfc";
    strcpy(word, "pizza");
    printf("%s", word);
    return 0;
}
#include <stdio.h>

int main(void){
    char words[][5] = {"cat", "dog", "bird"};
    printf("%s\n", words[1]);
    printf("%c\n", words[2][3]);
    return 0;
}
// Week 5 Lecture COMP1511
// Word Guess
//
// A word guessing game where the player guesses the whole word.
// Each incorrect guess reveals another letter, starting from the end.
// The player can also exit using Ctrl+D.

#include <stdio.h>
#include <string.h>

#define MAX_WORD_LENGTH 50
#define MAX_GUESSES 4

void game_loop(char word[], char hidden[]);
void print_game(char hidden[], int guesses_left);
void remove_trailing_nl(char s[]);
void reveal_clue(char word[], char hidden[]);

int main(void) {
    char word[MAX_WORD_LENGTH] = "potato";
    char hidden[MAX_WORD_LENGTH] = "------";
    printf("Welcome to MyWord\n");

    game_loop(word, hidden);

    return 0;
}

// STAGE 1: read in a guess and check if it is correct!
// STAGE 2: loop till CtrlD
// STAGE 3: finish if no more guesses or correct
// STAGE 4: reveal clues
void game_loop(char word[], char hidden[]) {
    char guess[MAX_WORD_LENGTH];
    print_game(hidden, MAX_GUESSES);
    int guesses_left = MAX_GUESSES;
    int game_over = 0;
    while (game_over == 0 && fgets(guess, MAX_WORD_LENGTH, stdin) != NULL) {
        remove_trailing_nl(guess);
        if (strcmp(guess, word) == 0) {
            printf("Correct! You win\n");
            game_over = 1;
            // return;
        } else {
            printf("Wrong!!!\n");
            guesses_left--;
            if (guesses_left == 0) {
                printf("No guesses left!\n");
                game_over = 1;
            } else {
                reveal_clue(word, hidden);
                print_game(hidden, guesses_left);
            }
        }
        
    }
}

void remove_trailing_nl(char s[]) {
    int len = strlen(s); //4
    if (len > 0 && s[len - 1] == '\n') {
        s[len - 1] = '\0';
    }
}

void reveal_clue(char word[], char hidden[]) {
    int i = strlen(hidden)  - 1;
    while (i >= 0 && hidden[i] != '-') {
        i--;
    }
    
    hidden[i] = word[i];
}

// Prints the current game state and prompts for a guess.
void print_game(char hidden[], int guesses_left) {
    printf("\nWord: %s\n", hidden);
    printf("Guesses left: %d\n", guesses_left);
    printf("Guess the word: ");
}
// Week 5 Lecture COMP1511
// Word Guess
//
// A word guessing game where the player guesses the whole word.
// Each incorrect guess reveals another letter, starting from the end.
// The player can also exit using Ctrl+D.

#include <stdio.h>
#include <string.h>

#define MAX_WORD_LENGTH 50
#define MAX_GUESSES 4

void game_loop(char word[], char hidden[]);
void print_game(char hidden[], int guesses_left);

int main(void) {
    char word[MAX_WORD_LENGTH] = "potato";
    char hidden[MAX_WORD_LENGTH] = "------";
    printf("Welcome to MyWord\n");

    game_loop(word, hidden);

    return 0;
}

// STAGE 1: read in a guess and check if it is correct!
// STAGE 2: loop till CtrlD
// STAGE 3: finish if no more guesses or correct
// STAGE 4: reveal clues
void game_loop(char word[], char hidden[]) {
    print_game(hidden, MAX_GUESSES);
}


// Prints the current game state and prompts for a guess.
void print_game(char hidden[], int guesses_left) {
    printf("\nWord: %s\n", hidden);
    printf("Guesses left: %d\n", guesses_left);
    printf("Guess the word: ");
}
// Week 5 lecture
// showing the use of atoi
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int sum = 0;
    for (int i = 1; i < argc; i++) {
        // atoi converts a string to an int
        // For example atoi("123") would return the int 123.
        sum = sum + atoi(argv[i]);
    }
    printf("%d is the sum of all command line args\n", sum);
    return 0;
}
// Week 5 lecture
// This does not work
// Even if we run
// ./bad_sum 99 -127 918
// 99 etc is the string "99" which is an array of char
// We can't do maths on it

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int sum = 0;
    for (int i = 1; i < argc; i++) {
        sum = sum + argv[i];
    }
    printf("%d is the sum of all command line args\n", sum);
    return 0;
}
// Week 5 Lecture
// showing the use of command line arguments
// For example you can run this program like
// ./command_line_args "hello world" 5 BLAH
// 

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("\nThere are %d command line arguments\n", argc);
   
    // argv[0] is always the program name
    printf("This program name is %s\n", argv[0]);

    // print out all arguments in the argv array
    for (int i = 0; i < argc; i++) {
        printf("Argument at index %d is %s\n", i, argv[i]);
    }
    return 0;
}
// COMP1511 Week 5
// Making pointers point to different things

#include <stdio.h>

int main(void) {
    int x = 3;  
    int y = 7;
    int *x_ptr = &x;
    int *num_ptr = x_ptr; 

    // What will this print?
    printf("%d %d %d %d\n", x, y, *x_ptr, *num_ptr);

    *num_ptr = 10; 
    // What will this print now?
    printf("%d %d %d %d\n", x, y, *x_ptr, *num_ptr);

    // num_ptr is pointing somewhere else now
    num_ptr = &y;

    // What will this print now?
    printf("%d %d %d %d\n", x, y, *x_ptr, *num_ptr);

    y = 99;
    // What will this print now?
    printf("%d %d %d %d\n", x, y, *x_ptr, *num_ptr);

    
    double d = 1.5;
    num_ptr = &d; //INVALID C CODE

    
    return 0;     
}
// COMP1511 Week 5
// Exercise. 
// Try to read and work out what it will print
// before running the code.

#include <stdio.h>

int main(void) {
    int x = -7;
    int y = 5;
    
    int *ptr1 = &y;
    int *ptr2 = &x;
    
    int z = *ptr1 + y;
    
    *ptr2 = z - 1;
    printf("%d %d %d\n", x, y, z);
    
    ptr2 = ptr1;
    printf("%d %d\n", *ptr1, *ptr2);

    return 0;
}
// COMP1511 Week 5
// Introduction to basic pointer concepts
// Address of operator &
// Declaring and initialised pointer variables
// Dereferencing pointer variables

#include <stdio.h>

int main(void) {
    // Decare and initialise a normal int variable called 'x'
    int x = 2;   

    // Print the address and value of x
    printf("The int that x stores (x): %d\n", x);
    printf("The address of x (&x): %p\n", &x);
    
    // Declare a pointer variable 'x_ptr' and 
    // assign the address of 'x' to it
    int *x_ptr = &x;

    // Print the addresses and value of x_ptr
    printf("The address that x_ptr stores (x_ptr): %p\n", x_ptr);
    printf("The address of x_ptr (&x_ptr): %p\n", &x_ptr);
    
    // Dereference 'x_ptr'
    printf("x_ptr (*x_ptr): %d\n", *x_ptr);

    return 0;     
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
// so changes made in the function are on the local copy

#include <stdio.h>

void update(int x, int y);
void swap(int x, int y);

int main(void) {
    int x = 2;
    int y = 5;

    printf("%d %d\n", x, y);
    
    update(x,y);
    printf("%d %d\n", x, y);
    
    swap(x, y);
    printf("%d %d\n", x, y);
    return 0;
}

// This function will only modify the local copy of x and y
void update(int x, int y) {
    x = x + 1;
    y = y - 1;
}

// This function will only modify the local copy of x and y
void swap(int x, int y) {
    int tmp = x;
    x = y;
    y = tmp;
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
// Here we pass in the addresses of the variables
// so we can go directly to their address and modify
// them from within the function

#include <stdio.h>

void update(int *x, int *y);
// TO DO FIX SWAP
void swap(int *x, int *y);

int main(void) {
    int x = 2;
    int y = 5;

    printf("%d %d\n", x, y);
    
    // Pass in the addresses of x and y
    // So update can use the addresses to
    // go modify x and y 
    update(&x, &y);
    printf("%d %d\n", x, y);
    
    //TODO FIX THIS
    swap(&x, &y);
    printf("%d %d\n", x, y);
    return 0;
}

// This function uses pointers.
// We can dereference x and y and modify the data
// at the given addresses
void update(int *x, int *y) {
    *x = *x + 1;
    *y = *y - 1;
}

// This function will only modify the local copy of x and y
// TODO FIX
void swap(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function

#include <stdio.h>

struct point {
    int x;
    int y;
};

void update(struct point p);

int main(void) {
    struct point p;    
    p.x = 10;
    p.y = 9;
    update(p);
	printf("(%d,%d)\n", p.x, p.y);
    return 0;
}

// This function will only modify the local copy of p
void update(struct point p) {
    p.x = p.x + 1;
    p.y = p.y + 1;
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
// TO DO MODIFY THIS TO USE POINTERS

#include <stdio.h>

struct point {
    int x;
    int y;
};

void update(struct point my_point);

int main(void) {
    struct point p;    
    p.x = 10;
    p.y = 9;

    update(p);
    printf("(%d,%d)\n", p.x, p.y);
    //Could we do without pointers?
   
    return 0;
}

// This function will only modify the local copy of p
// Modify this version to use pointers.
void update(struct point my_point) {
    my_point.x = my_point.x + 1;  
    my_point.y = my_point.y + 1;  
}