Programming Fundamentals
Information
- This page contains additional revision exercises for week 06.
- These exercises are not compulsory, nor do they provide any marks in the course.
- You cannot submit any of these exercises, however autotests may be available for some them (Command included at bottom of each exercise if applicable).
Exercise — individual:
String Manipulation (Revision Session Exercise)
Copy the file(s) for this exercise to your CSE account using the following command:
1511 fetch-revision 06
Implement the different functions listed in the string_manipulation.c
file.
No autotests are provided for this question.
Examples
dcc struct_tutorial.c -o struct_tutorial ./struct_tutorial Hello, World! Goodbye Goodbye is before World.
string_manipulation.c
// Strings
// Some string practice:
// - declaring & initialising
// - printing
// - scanning a string
// - count vowels and consonants
// - check string equality (check if 2 strings are the same)
// - reverse a string
// - string concatenation (adding a string to the end of another)
// - title case conversion (every first letter in a word becomes a capital)
// - count words (words are a series of characters surrounded by spaces)
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_STR_LEN 1024
void count_vowels_consonants(char *string);
int is_vowel(char letter);
void reverse_string(char *string);
void string_concatenation(char *string1, char *string2);
void title_case_conversion(char *string);
void count_words(char *string);
int main(void) {
// MOST IMPORTANT/USEFUL:
// Declare & Initialise a String
char str1[MAX_STR_LEN] = "Hello, World!\n";
// Print a string
printf("%s", str1);
// Scan a string from stdin
fgets(str1, MAX_STR_LEN, stdin);
str1[strcspn(str1, "\n")] = '\0';
// Check if a string is the same as another
char str2[] = "World";
if (strcmp(str1, str2) == 0) {
printf("%s and %s are the same.\n", str1, str2);
} else if (strcmp(str1, str2) < 0) {
printf("%s is before %s.\n", str1, str2);
} else {
printf("%s is before %s.\n", str2, str1);
}
// Copy a string into another
strcpy(str2, str1);
printf("str2 is now %s.\n", str2);
// LESS IMPORTANT/EXTRA PROBLEM SOLVING
// Count Vowels and Consonants
count_vowels_consonants(str1);
// Reverse a String
reverse_string(str1);
// String Concatenation
string_concatenation(str1, "END");
// Can just use the function strcat
// strncat(str1, "END");
printf("%s\n", str1);
// Title Case Conversion
title_case_conversion(str1);
printf("%s\n", str1);
// Count Words
count_words(str1);
}
void count_vowels_consonants(char *string) {
int vowel_count = 0;
int consonant_count = 0;
for (int i = 0; string[i] != '\0'; i++) {
if (is_vowel(string[i])) {
vowel_count++;
} else if (isalpha(string[i])) {
consonant_count++;
}
}
printf("There are %d vowels and %d consonants.\n", vowel_count, consonant_count);
}
int is_vowel(char letter) {
letter = tolower(letter);
if (letter == 'a') {
return 1;
} else if (letter == 'e') {
return 1;
} else if (letter == 'i') {
return 1;
} else if (letter == 'o') {
return 1;
} else if (letter == 'u') {
return 1;
}
return 0;
}
void reverse_string(char *string) {
char reversed[MAX_STR_LEN];
for (int i = 0, j = strlen(string) - 1; j >= 0; i++, j--) {
reversed[i] = string[j];
}
reversed[strlen(string)] = '\0';
printf("%s\n", reversed);
}
void string_concatenation(char *string1, char *string2) {
int i = 0;
while (string1[i] != '\0') {
i++;
}
int j = 0;
while (j < strlen(string2)) {
string1[i] = string2[j];
i++;
j++;
}
string1[i] = '\0';
}
void title_case_conversion(char *string) {
int prev = 1;
for (int i = 0; string[i] != '\0'; i++) {
if (prev) {
string[i] = toupper(string[i]);
}
if (string[i] == ' ') {
prev = 1;
} else {
prev = 0;
}
}
}
void count_words(char *string) {
int prev = 1;
int word_count = 0;
for (int i = 0; string[i] != '\0'; i++) {
if (prev && isalpha(string[i])) {
word_count++;
}
if (string[i] == ' ') {
prev = 1;
} else {
prev = 0;
}
}
printf("There are %d words in this sentence.\n", word_count);
}
Exercise — individual:
Simple Frogger (Revision Session Exercise)
Copy the file(s) for this exercise to your CSE account using the following command:
1511 fetch-revision 06
Complete the program simple_frogger.c
, which is a simple version of the classic Frogger arcade game.
The game should start by printing a 9 x 9 map, to be built as follows:
- The Top Row alternates between house
|^|
and grass-
. - Next 3 rows are water
~
, where logs-_-
and alligatorsA
can be added later. - Next row is grass
-
. - Next 3 rows is road
=
, where carsC
can be added later. - Bottom row is grass
-
.
The game then prompts the user to:
- Enter a column to place Frogger
!F!
on. - Enter the row, column, and length of 3 logs in the water. These will be used to get Frogger across the river as it cannot jump onto the water.
- Enter the type, row, and column of 3 enemies which can be
- Alligators (in the water)
- Cars (on the road)
Once these elements have been added to the map, Frogger can start moving through the map using:
u
to move upd
to move downl
to move leftr
to move right
Frogger wins if it makes it to a house tile |^|
.
Frogger loses if it goes into the water ~
, or on an alligator A
or car C
.
No autotests are provided for this question.
Examples
dcc simple_frogger.c -o simple_frogger ./simple_frogger Welcome to the simple game of Frogger! |^| - |^| - |^| - |^| - |^| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - - - - - - - =========================== =========================== =========================== - - - - - - - - - Please enter frogger's starting column: 4 |^| - |^| - |^| - |^| - |^| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - - - - - - - =========================== =========================== =========================== - - - - !F! - - - - Enter 3 logs: 1 2 4 2 5 3 3 4 2 Enter 3 enemies. Type + row + col: 1 5 3 1 7 4 2 2 4 |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ============ C ============ - - - - !F! - - - - Enter movement: u Game over! dcc simple_frogger.c -o simple_frogger ./simple_frogger Welcome to the simple game of Frogger! |^| - |^| - |^| - |^| - |^| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - - - - - - - =========================== =========================== =========================== - - - - - - - - - Please enter frogger's starting column: 5 |^| - |^| - |^| - |^| - |^| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - - - - - - - =========================== =========================== =========================== - - - - - !F! - - - Enter 3 logs: 1 2 4 2 5 3 3 4 2 Enter 3 enemies. Type + row + col: 1 5 3 1 7 6 2 2 4 |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ================== C ====== - - - - - !F! - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ===============!F! C ====== - - - - - - - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== ===============!F!========= ================== C ====== - - - - - - - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C ===!F!========= =========================== ================== C ====== - - - - - - - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - !F! - - - ========= C =============== =========================== ================== C ====== - - - - - - - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_-!F!~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ================== C ====== - - - - - - - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_--_-~~~~~~~~~ ~~~~~~~~~~~~ A !F!-_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ================== C ====== - - - - - - - - - Enter movement: u |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_--_-!F!~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ================== C ====== - - - - - - - - - Enter movement: l |^| - |^| - |^| - |^| - |^| ~~~~~~-_--_-!F!-_-~~~~~~~~~ ~~~~~~~~~~~~ A -_--_--_-~~~ ~~~~~~~~~~~~-_--_-~~~~~~~~~ - - - - - - - - - ========= C =============== =========================== ================== C ====== - - - - - - - - - Enter movement: u Game won!
Assumptions/Restrictions/Clarifications
- Error checking is not needed. You can assume only valid inputs will be given.
- Apart from Frogger, the map elements will not move during the game.
simple_frogger.c
// Simple Frogger
//
// A simple version of the classic Frogger arcade game where frogger
// is placed on a 9 x 9 map which is built as follows:
// Top row: House Grass House Grass House
// Next 3 rows: Water with logs & alligators
// Next 1 row: Grass
// Next 3 rows: Road with cars
// Bottom row: Grass
// Frogger moves through the map using 'u', 'l', 'd', 'r'
// Frogger wins if it makes it to a house tile
// Frogger loses if it goes into the water, or on an alligator or car
// The map is generated and is not changed again (i.e. cars, alligators and logs
// stay where originally placed)
// Error checking not needed, it can be assumed only valid inputs will be given
#include <stdio.h>
#define MAX_SIZE 9
enum tile_type {
GRASS,
ROAD,
WATER,
LOG,
HOUSE,
};
enum enemy {
NO_ENEMY,
CAR,
ALLIGATOR,
};
struct tile {
enum tile_type type;
enum enemy enemy;
int frogger;
};
void initialise_map(struct tile map[][MAX_SIZE]);
void print_map(struct tile map[][MAX_SIZE]);
int move_frogger(struct tile map[][MAX_SIZE], int move_row, int move_col);
void prepare_map(struct tile map[][MAX_SIZE]);
int play_turn(struct tile map[][MAX_SIZE]);
int main(void) {
printf("Welcome to the simple game of Frogger!\n");
// declare & initialise map
struct tile map[MAX_SIZE][MAX_SIZE];
initialise_map(map);
print_map(map);
// add frogger, logs and enemies
prepare_map(map);
// play turns until frogger wins or loses
int game_over = 0;
while (game_over == 0) {
game_over = play_turn(map);
}
if (game_over == 1) {
printf("Game won!\n");
} else {
printf("Game over!\n");
}
return 0;
}
void initialise_map(struct tile map[][MAX_SIZE]) {
// set 0 row to be grass & house
int row = 0;
int col = 0;
while (col < MAX_SIZE) {
if (col % 2 == 0) {
map[row][col].type = HOUSE;
} else {
map[row][col].type = GRASS;
}
col++;
}
// set 1, 2 & 3 rows to be water
row++;
while (row < 4) {
col = 0;
while (col < MAX_SIZE) {
map[row][col].type = WATER;
col++;
}
row++;
}
// set 4 row to be grass
col = 0;
while (col < MAX_SIZE) {
map[row][col].type = GRASS;
col++;
}
// set 5, 6 & 7 rows to be road
row++;
while (row < 8) {
col = 0;
while (col < MAX_SIZE) {
map[row][col].type = ROAD;
col++;
}
row++;
}
// set row 8 to be grass
col = 0;
while (col < MAX_SIZE) {
map[row][col].type = GRASS;
col++;
}
// set everything to not be frogger & not be an enemy
for (row = 0; row < MAX_SIZE; row++) {
for (col = 0; col < MAX_SIZE; col++) {
map[row][col].frogger = 0;
map[row][col].enemy = NO_ENEMY;
}
}
}
void print_map(struct tile map[][MAX_SIZE]) {
for (int row = 0; row < MAX_SIZE; row++) {
for (int col = 0; col < MAX_SIZE; col++) {
if (map[row][col].frogger) {
printf("!F!");
} else if (map[row][col].enemy == CAR) {
printf(" C ");
} else if (map[row][col].enemy == ALLIGATOR) {
printf(" A ");
} else if (map[row][col].type == GRASS) {
printf(" - ");
} else if (map[row][col].type == ROAD) {
printf("===");
} else if (map[row][col].type == WATER) {
printf("~~~");
} else if (map[row][col].type == LOG) {
printf("-_-");
} else if (map[row][col].type == HOUSE) {
printf("|^|");
}
}
printf("\n");
}
}
int move_frogger(struct tile map[][MAX_SIZE], int move_row, int move_col) {
// find frogger
for (int i = 0; i < MAX_SIZE; i++) {
for (int j = 0; j < MAX_SIZE; j++) {
if (map[i][j].frogger) {
// update old spot to no longer hold frogger
map[i][j].frogger = 0;
int new_row = i + move_row;
int new_col = j + move_col;
// update new spot to hold frogger
map[new_row][new_col].frogger = 1;
// if new spot is house, frogger wins
if (map[new_row][new_col].type == HOUSE) {
return 1;
}
// if new spot is water or enemy, frogger loses
if (map[new_row][new_col].enemy != NO_ENEMY || map[new_row][new_col].type == WATER) {
return -1;
}
return 0;
}
}
}
return 0;
}
void prepare_map(struct tile map[][MAX_SIZE]) {
printf("Please enter frogger's starting column: ");
int frogger_row = MAX_SIZE - 1;
int frogger_col;
scanf("%d", &frogger_col);
map[frogger_row][frogger_col].frogger = 1;
print_map(map);
printf("Enter 3 logs:\n");
int row;
int col;
int length;
for (int i = 0; i < 3; i++) {
scanf("%d %d %d", &row, &col, &length);
for (int j = 0; j < length; j++) {
map[row][col].type = LOG;
col++;
}
}
printf("Enter 3 enemies. Type + row + col:\n");
for (int i = 0; i < 3; i++) {
int type;
scanf("%d %d %d", &type, &row, &col);
map[row][col].enemy = type;
}
}
int play_turn(struct tile map[][MAX_SIZE]) {
print_map(map);
printf("Enter movement: ");
char move;
scanf(" %c", &move);
if (move == 'u') {
return move_frogger(map, -1, 0);
} else if (move == 'd') {
return move_frogger(map, 1, 0);
} else if (move == 'l') {
return move_frogger(map, 0, -1);
} else if (move == 'r') {
return move_frogger(map, 0, 1);
} else {
return 0;
}
}
Exercise — individual:
CS Calculator Style (Revision Session Exercise)
Copy the file(s) for this exercise to your CSE account using the following command:
1511 fetch-revision 06
Although this cs_calculator.style.c
program runs properly, the style is horrendous! Please help us fix up the style.
No autotests are provided for this question.
cs_calculator_style.c
// Author: Dean Wunder
// d.wunder@unsw.edu.au
// 2020-05-04
// A arbitrary calculator app designed to help students
// understand variable length input scanning before assignment 1.
#include <stdio.h>
#define SQUARE_COMMAND 's'
#define POWER_COMMAND 'p'
int main (void) {
char command;
printf("Enter instruction: ");
while (scanf(" %c", &command) == 1) {
if (command == SQUARE_COMMAND) {
int num;
scanf("%d", &num);
printf("%d\n", num * num);
} else if (command == POWER_COMMAND) {
int base, power;
scanf("%d %d", &base, &power);
int i = 0;
int result = 1;
while (i < power) {
result *= base;
i++;
}
printf("%d\n", result);
}
printf("Enter instruction: ");
}
return 0;
}