mirror of https://github.com/01-edu/public.git
Chris
4 years ago
57 changed files with 2334 additions and 77 deletions
@ -0,0 +1,16 @@
|
||||
objects = src/main.o src/system.o src/auth.o
|
||||
|
||||
atm : $(objects) |
||||
cc -o atm $(objects)
|
||||
|
||||
main.o : src/header.h |
||||
kbd.o : src/header.h |
||||
command.o : src/header.h |
||||
display.o : src/header.h |
||||
insert.o : src/header.h |
||||
search.o : src/header.h |
||||
files.o : src/header.h |
||||
utils.o : src/header.h |
||||
|
||||
clean : |
||||
rm -f $(objects)
|
@ -0,0 +1,6 @@
|
||||
Alice 0 10/10/2012 Africa 291321234 22432.52 saving |
||||
|
||||
Michel 2 2/5/2001 Portugal 123543455 10023.230000 fixed01 |
||||
|
||||
Michel 123 10/10/2020 UK 1234123 12345.30 saving |
||||
|
@ -0,0 +1,2 @@
|
||||
Alice q1w2e3r4t5y6 |
||||
Michel q1w2e3r4t5y6 |
@ -0,0 +1,59 @@
|
||||
#include <termios.h> |
||||
#include "header.h" |
||||
|
||||
char *USERS = "./data/users.txt"; |
||||
|
||||
void loginMenu(char a[50], char pass[50]) |
||||
{ |
||||
struct termios oflags, nflags; |
||||
|
||||
system("clear"); |
||||
printf("\n\n\n\t\t\t\t Bank Management System\n\t\t\t\t\t User Login:"); |
||||
scanf("%s", a); |
||||
|
||||
// disabling echo
|
||||
tcgetattr(fileno(stdin), &oflags); |
||||
nflags = oflags; |
||||
nflags.c_lflag &= ~ECHO; |
||||
nflags.c_lflag |= ECHONL; |
||||
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) |
||||
{ |
||||
perror("tcsetattr"); |
||||
return exit(1); |
||||
} |
||||
printf("\n\n\n\n\n\t\t\t\tEnter the password to login:"); |
||||
scanf("%s", pass); |
||||
|
||||
// restore terminal
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) |
||||
{ |
||||
perror("tcsetattr"); |
||||
return exit(1); |
||||
} |
||||
}; |
||||
|
||||
const char *getPassword(struct User u) |
||||
{ |
||||
FILE *fp; |
||||
struct User userChecker; |
||||
|
||||
if ((fp = fopen("./data/users.txt", "r")) == NULL) |
||||
{ |
||||
printf("Error! opening file"); |
||||
exit(1); |
||||
} |
||||
|
||||
while (fscanf(fp, "%s %s", userChecker.name, userChecker.password) != EOF) |
||||
{ |
||||
if (strcmp(userChecker.name, u.name) == 0) |
||||
{ |
||||
fclose(fp); |
||||
char *buff = userChecker.password; |
||||
return buff; |
||||
} |
||||
} |
||||
|
||||
fclose(fp); |
||||
return "no user found"; |
||||
} |
@ -0,0 +1,37 @@
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
struct Date |
||||
{ |
||||
int month, day, year; |
||||
}; |
||||
|
||||
// all fields for each record of an account
|
||||
struct Record |
||||
{ |
||||
char name[100]; |
||||
char country[100]; |
||||
int phone; |
||||
char accountType[10]; |
||||
int accountNbr; |
||||
double amount; |
||||
struct Date deposit; |
||||
struct Date withdraw; |
||||
}; |
||||
|
||||
struct User |
||||
{ |
||||
char name[50]; |
||||
char password[50]; |
||||
}; |
||||
|
||||
// authentication functions
|
||||
void loginMenu(char a[50], char pass[50]); |
||||
void registerMenu(char a[50], char pass[50]); |
||||
const char *getPassword(struct User u); |
||||
|
||||
// system function
|
||||
void createNewAcc(struct User u); |
||||
void mainMenu(struct User u); |
||||
void checkAllAccounts(struct User u); |
@ -0,0 +1,104 @@
|
||||
#include "header.h" |
||||
|
||||
void mainMenu(struct User u) |
||||
{ |
||||
int option; |
||||
system("clear"); |
||||
printf("\n\n\t\t======= ATM =======\n\n"); |
||||
printf("\n\t\t-->> Feel free to choose one of the options below <<--\n"); |
||||
printf("\n\t\t[1]- Create a new account\n"); |
||||
printf("\n\t\t[2]- Update information of account\n"); |
||||
printf("\n\t\t[3]- Check accounts\n"); |
||||
printf("\n\t\t[4]- Check list of owned account\n"); |
||||
printf("\n\t\t[5]- Make Transaction\n"); |
||||
printf("\n\t\t[6]- Remove existing account\n"); |
||||
printf("\n\t\t[7]- Transfer ownership\n"); |
||||
printf("\n\t\t[8]- Exit\n"); |
||||
scanf("%d", &option); |
||||
|
||||
switch (option) |
||||
{ |
||||
case 1: |
||||
createNewAcc(u); |
||||
break; |
||||
case 2: |
||||
// student TODO : add your **Update information of existing account** function
|
||||
// here
|
||||
break; |
||||
case 3: |
||||
// student TODO : add your **Check the details of existing accounts** function
|
||||
// here
|
||||
break; |
||||
case 4: |
||||
checkAllAccounts(u); |
||||
break; |
||||
case 5: |
||||
// student TODO : add your **Make transaction** function
|
||||
// here
|
||||
break; |
||||
case 6: |
||||
// student TODO : add your **Remove existing account** function
|
||||
// here
|
||||
break; |
||||
case 7: |
||||
// student TODO : add your **Transfer owner** function
|
||||
// here
|
||||
break; |
||||
case 8: |
||||
exit(1); |
||||
break; |
||||
default: |
||||
printf("Invalid operation!\n"); |
||||
} |
||||
}; |
||||
|
||||
void initMenu(struct User *u) |
||||
{ |
||||
int r = 0; |
||||
int option; |
||||
system("clear"); |
||||
printf("\n\n\t\t======= ATM =======\n"); |
||||
printf("\n\t\t-->> Feel free to login / register :\n"); |
||||
printf("\n\t\t[1]- login\n"); |
||||
printf("\n\t\t[2]- register\n"); |
||||
printf("\n\t\t[3]- exit\n"); |
||||
while (!r) |
||||
{ |
||||
scanf("%d", &option); |
||||
switch (option) |
||||
{ |
||||
case 1: |
||||
loginMenu(u->name, u->password); |
||||
if (strcmp(u->password, getPassword(*u)) == 0) |
||||
{ |
||||
printf("\n\nPassword Match!"); |
||||
} |
||||
else |
||||
{ |
||||
printf("\nWrong password!! or User Name\n"); |
||||
exit(1); |
||||
} |
||||
r = 1; |
||||
break; |
||||
case 2: |
||||
// student TODO : add your **Registration** function
|
||||
// here
|
||||
r = 1; |
||||
break; |
||||
case 3: |
||||
exit(1); |
||||
break; |
||||
default: |
||||
printf("Insert a valid operation!\n"); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
int main() |
||||
{ |
||||
struct User u; |
||||
|
||||
initMenu(&u); |
||||
mainMenu(u); |
||||
return 0; |
||||
} |
@ -0,0 +1,161 @@
|
||||
#include "header.h" |
||||
|
||||
const char *RECORDS = "./data/records.txt"; |
||||
|
||||
int getAccountFromFile(FILE *ptr, char name[50], struct Record *r) |
||||
{ |
||||
return fscanf(ptr, "%s %d %d/%d/%d %s %d %lf %s", |
||||
name, |
||||
&r->accountNbr, |
||||
&r->deposit.month, |
||||
&r->deposit.day, |
||||
&r->deposit.year, |
||||
r->country, |
||||
&r->phone, |
||||
&r->amount, |
||||
r->accountType) != EOF; |
||||
} |
||||
|
||||
void saveAccountToFile(FILE *ptr, char name[50], struct Record r) |
||||
{ |
||||
fprintf(ptr, "%s %d %d/%d/%d %s %d %.2lf %s\n\n", |
||||
name, |
||||
r.accountNbr, |
||||
r.deposit.month, |
||||
r.deposit.day, |
||||
r.deposit.year, |
||||
r.country, |
||||
r.phone, |
||||
r.amount, |
||||
r.accountType); |
||||
} |
||||
|
||||
void stayOrReturn(int notGood, void f(struct User u), struct User u) |
||||
{ |
||||
int option; |
||||
if (notGood == 0) |
||||
{ |
||||
system("clear"); |
||||
printf("\n✖ Record not found!!\n"); |
||||
invalid: |
||||
printf("\nEnter 0 to try again, 1 to return to main menu and 2 to exit:"); |
||||
scanf("%d", &option); |
||||
if (option == 0) |
||||
f(u); |
||||
else if (option == 1) |
||||
mainMenu(u); |
||||
else if (option == 2) |
||||
exit(0); |
||||
else |
||||
{ |
||||
printf("Insert a valid operation!\n"); |
||||
goto invalid; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
printf("\nEnter 1 to go to the main menu and 0 to exit:"); |
||||
scanf("%d", &option); |
||||
} |
||||
if (option == 1) |
||||
{ |
||||
system("clear"); |
||||
mainMenu(u); |
||||
} |
||||
else |
||||
{ |
||||
system("clear"); |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
void success(struct User u) |
||||
{ |
||||
int option; |
||||
printf("\n✔ Success!\n\n"); |
||||
invalid: |
||||
printf("Enter 1 to go to the main menu and 0 to exit!\n"); |
||||
scanf("%d", &option); |
||||
system("clear"); |
||||
if (option == 1) |
||||
{ |
||||
mainMenu(u); |
||||
} |
||||
else if (option == 0) |
||||
{ |
||||
exit(1); |
||||
} |
||||
else |
||||
{ |
||||
printf("Insert a valid operation!\n"); |
||||
goto invalid; |
||||
} |
||||
} |
||||
|
||||
void createNewAcc(struct User u) |
||||
{ |
||||
struct Record r; |
||||
struct Record cr; |
||||
char userName[50]; |
||||
FILE *pf = fopen(RECORDS, "a+"); |
||||
|
||||
noAccount: |
||||
system("clear"); |
||||
printf("\t\t\t===== New record =====\n"); |
||||
|
||||
printf("\nEnter today's date(mm/dd/yyyy):"); |
||||
scanf("%d/%d/%d", &r.deposit.month, &r.deposit.day, &r.deposit.year); |
||||
printf("\nEnter the account number:"); |
||||
scanf("%d", &r.accountNbr); |
||||
|
||||
while (getAccountFromFile(pf, userName, &cr)) |
||||
{ |
||||
if (strcmp(userName, u.name) == 0 && cr.accountNbr == r.accountNbr) |
||||
{ |
||||
printf("✖ This Account already exists for this user\n\n"); |
||||
goto noAccount; |
||||
} |
||||
} |
||||
printf("\nEnter the country:"); |
||||
scanf("%s", r.country); |
||||
printf("\nEnter the phone number:"); |
||||
scanf("%d", &r.phone); |
||||
printf("\nEnter amount to deposit: $"); |
||||
scanf("%lf", &r.amount); |
||||
printf("\nChoose the type of account:\n\t-> saving\n\t-> current\n\t-> fixed01(for 1 year)\n\t-> fixed02(for 2 years)\n\t-> fixed03(for 3 years)\n\n\tEnter your choice:"); |
||||
scanf("%s", r.accountType); |
||||
|
||||
saveAccountToFile(pf, u.name, r); |
||||
|
||||
fclose(pf); |
||||
success(u); |
||||
} |
||||
|
||||
void checkAllAccounts(struct User u) |
||||
{ |
||||
char userName[100]; |
||||
struct Record r; |
||||
|
||||
FILE *pf = fopen(RECORDS, "r"); |
||||
|
||||
system("clear"); |
||||
printf("\t\t====== All accounts from user, %s =====\n\n", u.name); |
||||
while (getAccountFromFile(pf, userName, &r)) |
||||
{ |
||||
if (strcmp(userName, u.name) == 0) |
||||
{ |
||||
printf("_____________________\n"); |
||||
printf("\nAccount number:%d\nDeposit Date:%d/%d/%d \ncountry:%s \nPhone number:%d \nAmount deposited: $%.2f \nType Of Account:%s\n", |
||||
r.accountNbr, |
||||
r.deposit.day, |
||||
r.deposit.month, |
||||
r.deposit.year, |
||||
r.country, |
||||
r.phone, |
||||
r.amount, |
||||
r.accountType); |
||||
} |
||||
} |
||||
fclose(pf); |
||||
success(u); |
||||
} |
@ -0,0 +1,95 @@
|
||||
#### Functional |
||||
|
||||
##### Open the application and register a new user with the name `"Alice"` and the password `"q1w2e3r4t5y6"`. |
||||
|
||||
###### Is this user saved in the file `"./data/users.txt"`, and if so, are all credentials correct (name and password)? |
||||
|
||||
##### Open the application and re-register the user `"Alice"`. |
||||
|
||||
###### Did it display an error message stating that this user already exist? |
||||
|
||||
##### Open the file `"./data/users.txt"`. |
||||
|
||||
###### Are all the user's names unique? (ex: no repetition on the name Alice) |
||||
|
||||
##### Try and login as `"Alice"`. |
||||
|
||||
###### Was Alice able to enter the main menu? |
||||
|
||||
##### Try to create two accounts using the user Alice, then select the option `"Update information of account"` and select an account number that does not exist for Alice. |
||||
|
||||
###### Did the application displayed some kind of error message stating that this account does not exist? |
||||
|
||||
##### Resorting to the user Alice, try and select the option `"Update information of account"` and select one of the accounts you created for Alice. |
||||
|
||||
###### Did the the application prompt a choice of updating the **phone number** or the **country**? |
||||
|
||||
##### Resorting to the user Alice, try and select the option `"Update information of account"` and select one of the accounts you created for Alice. Then update the phone number of that account. |
||||
|
||||
###### Was the phone number of that account updated in the application and the file `"records.txt"`? |
||||
|
||||
##### Resorting to the user Alice, try and select the option `"Update information of account"` and select one of the accounts you created for Alice. Then update the country of that account. |
||||
|
||||
###### Was the country of that account updated in the application and the file `"records.txt"`? |
||||
|
||||
##### Resorting to the user Alice, try to create a new account with: date `"10/10/2012"` account number `"834213"`, country `"UK"`, phone number `"291231392"`, deposit amount $`"1001.20"`, type of account `"saving"`. Then select `"Check accounts"` choose the account you just created. |
||||
|
||||
###### Did the application displayed the account information and the gain of $5.84 of interest on day 10 of every moth? |
||||
|
||||
##### Resorting to the user Alice create again an account but with account number "320421" and type of account "fixed01" with the rest of the information as in the last account . Then select `"Check accounts"` and choose the account you just created. |
||||
|
||||
###### Did the application displayed the account information and the gain of $40.05 of interest on 10/10/2013? |
||||
|
||||
##### Resorting to the user Alice create again an account but with account number `"3214"` and type of account `"fixed02"` with the rest of the information as in the last account. Then select `"Check accounts"` and choose the account you just created. |
||||
|
||||
###### Did the application displayed the account information and the gain of $100.12 of interest on 10/10/2014? |
||||
|
||||
##### Resorting to the user Alice create again an account but with account number `"3212"` and type of account `"fixed03"` with the rest of the information as in the last account. Then select `"Check accounts"` and choose the account you just created. |
||||
|
||||
###### Did the application displayed the account information and the gain of $240.29 of interest on 10/10/2015? |
||||
|
||||
##### Resorting to the user Alice select the option `"Make transaction"`. Then choose the account with the id `"3212"` |
||||
|
||||
###### Are you able to choose between withdrawing or depositing? |
||||
|
||||
##### Resorting to the user Alice select the option `"Make transaction"`, choose the account with the id `"3212"`. Then try to withdraw money. |
||||
|
||||
###### Are you able to withdraw money? |
||||
|
||||
###### And if so, was the withdraw updated in the file `"records.txt"`? |
||||
|
||||
###### Is it not possible to withdraw an amount superior to your available balance? |
||||
|
||||
##### Try to deposit money into the account `"3212"`. |
||||
|
||||
###### Were you able to deposit money into this account? |
||||
|
||||
###### And if so did it update the file `"records.txt"`? |
||||
|
||||
##### Resorting to the user Alice try to select the option `"Remove existing account"` and remove the accounts `"834213"`, `"320421"` and `"3214"`. |
||||
|
||||
###### Can you confirm that those account were deleted, both in the application and file `"records.txt"`? |
||||
|
||||
##### Resorting to the user Alice select the option `"Remove existing account"` and try to remove and nonexisting account. |
||||
|
||||
###### Did the application prompt some type of error saying that the account does not exists? |
||||
|
||||
##### Create another user named `"Michel"`. Then by using Alice select the option `"transfer owner"` and try to transfer ownership of the account `"3212"` to Michel. |
||||
|
||||
###### Were you able to transfer the ownership of this account to Michel? And if so did it update both application and file `"records.txt"`? |
||||
|
||||
#### Bonus |
||||
|
||||
##### Open two terminals and login with two different users. Then transfer ownership of an account to the other user. |
||||
|
||||
###### +Was the user whom received the account notified instantly? |
||||
|
||||
###### +Did the student update the terminal interface? |
||||
|
||||
###### +Is the password saved in the file `"users.txt"` encrypted? |
||||
|
||||
###### +Did the student make their own Makefile? |
||||
|
||||
###### +Did the student add more features to the project? |
||||
|
||||
###### +Did the student optimise the code already given? |
@ -0,0 +1,92 @@
|
||||
## blood_types_s |
||||
|
||||
### Instructions |
||||
|
||||
Use the following table to define the methods asked: |
||||
|
||||
| Blood Types | Donate Blood to | Receive Blood From | |
||||
|-------------|------------------|--------------------| |
||||
| A+ | A+, AB+ | A+, A-, O+, O- | |
||||
| O+ | O+, A+, B+, AB+ | O+, O- | |
||||
| B+ | O+, O- | B+, B-, O+, O- | |
||||
| AB+ | AB+ | Everyone | |
||||
| A- | A+, A-, AB+, AB- | A-, O- | |
||||
| O- | Everyone | O- | |
||||
| B- | B+, B-, AB+, AB- | B-, O- | |
||||
| AB- | AB+, AB- | AB-, A-, B-, O- | |
||||
|
||||
Write three methods for BloodType: |
||||
|
||||
- `can_receive_from`: which returns true if `self` can receive blood from `other` blood type |
||||
- `donors`: which returns all the blood types that can give blood to `self` |
||||
- `recipients`: which returns all the blood types that can receive blood from `self` |
||||
|
||||
### Expected Functions and Structures |
||||
|
||||
```rust |
||||
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)] |
||||
pub enum Antigen { |
||||
A, |
||||
AB, |
||||
B, |
||||
O, |
||||
} |
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] |
||||
enum RhFactor { |
||||
Positive, |
||||
Negative, |
||||
} |
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)] |
||||
pub struct BloodType { |
||||
pub antigen: Antigen, |
||||
pub rh_factor: RhFactor, |
||||
} |
||||
|
||||
impl BloodType { |
||||
pub fn can_receive_from(&self, other: &Self) -> bool { |
||||
} |
||||
|
||||
pub fn donors(&self) -> Vec<Self> { |
||||
} |
||||
|
||||
pub fn recipients(&self) -> Vec<Self> { |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function. |
||||
|
||||
```rust |
||||
use blood_types_s::{Antigen, BloodType, RhFactor}; |
||||
|
||||
fn main() { |
||||
let blood_type = BloodType { |
||||
antigen: Antigen::O, |
||||
rh_factor: RhFactor::Positive, |
||||
}; |
||||
println!("recipients of O+ {:?}", blood_type.recipients()); |
||||
println!("donors of O+ {:?}", blood_type.donors()); |
||||
let another_blood_type = BloodType { |
||||
antigen: Antigen::O, |
||||
rh_factor: RhFactor::Positive, |
||||
}; |
||||
println!( |
||||
"donors of O+ can receive from {:?} {:?}", |
||||
&another_blood_type, |
||||
blood_type.can_receive_from(&another_blood_type) |
||||
); |
||||
} |
||||
``` |
||||
|
||||
And its output |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
recipients of O+ [BloodType { antigen: AB, rh_factor: Positive }, BloodType { antigen: O, rh_factor: Positive }, BloodType { antigen: A, rh_factor: Positive }, BloodType { antigen: B, rh_factor: Positive }] |
||||
donors of O+ [BloodType { antigen: O, rh_factor: Positive }, BloodType { antigen: O, rh_factor: Negative }] |
||||
donors of O+ can receive from BloodType { antigen: O, rh_factor: Positive } true |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,42 @@
|
||||
## brain_fuck |
||||
|
||||
### Instructions |
||||
|
||||
Write a `Brainfuck` interpreter program. |
||||
The source code will be given as first parameter. |
||||
The code will always be valid, with less than 4096 operations. |
||||
`Brainfuck` is a minimalist language. It consists of an array of bytes (in this exercice 2048 bytes) all initialized with zero, and with a pointer to its first byte. |
||||
|
||||
Every operator consists of a single character : |
||||
|
||||
- '>' increment the pointer |
||||
- '<' decrement the pointer |
||||
- '+' increment the pointed byte |
||||
- '-' decrement the pointed byte |
||||
- '.' print the pointed byte on standard output |
||||
- '[' go to the matching ']' if the pointed byte is 0 (loop start) |
||||
- ']' go to the matching '[' if the pointed byte is not 0 (loop end) |
||||
|
||||
Any other character is a comment. |
||||
|
||||
For receiving arguments from the command line you should use something like: |
||||
|
||||
```rust |
||||
fn main() { |
||||
let args: Vec<String> = std::env::args().collect(); |
||||
|
||||
brain_fuck(&args[1]); |
||||
} |
||||
|
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
```console |
||||
$ cargo run "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." |
||||
Hello World! |
||||
$ cargo run "+++++[>++++[>++++H>+++++i<<-]>>>++\n<<<<-]>>--------.>+++++.>." |
||||
Hi |
||||
$ cargo run "++++++++++[>++++++++++>++++++++++>++++++++++<<<-]>---.>--.>-.>++++++++++." |
||||
abc |
||||
``` |
@ -0,0 +1,50 @@
|
||||
## counting_words |
||||
|
||||
### Instructions |
||||
|
||||
In this program you will have to create a function `counting_words` that |
||||
receives a `&str` and returns each word and the number of times it appears on the string. |
||||
|
||||
The program will count as a word the following: |
||||
|
||||
- A number like ("0" or "1234") will count as 1. |
||||
- A simple word or letter like ("a" or "they") will count as 1. |
||||
- Two simple words joined by a single apostrophe ("it's" or "they're") will count as 1. |
||||
|
||||
The program must respect the following rules: |
||||
|
||||
- The count is case insensitive ("HELLO", "Hello", and "hello") are 3 uses of the same word. |
||||
- All forms of punctuation have to be ignored except for the apostrophe if used like the example above. |
||||
- The words can be separated by any form of whitespace (ie "\t", "\n", " "). |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
fn counting_words(words: &str) -> HashMap<String, u32> {} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible program to test your function : |
||||
|
||||
```rust |
||||
use counting_words::counting_words; |
||||
use std::collections::HashMap; |
||||
|
||||
fn main() { |
||||
println!("{:?}", counting_words("Hello, world!")); |
||||
println!("{:?}", counting_words("“Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.” |
||||
― Albert Einstein ")); |
||||
println!("{:?}", counting_words("Batman, BATMAN, batman, Stop stop")); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
{"hello": 1, "world": 1} |
||||
{"and": 2, "human": 1, "universe": 2, "the": 2, "i\'m": 1, "about": 1, "einstein": 1, "are": 1, "infinite": 1, "sure": 1, "albert": 1, "two": 1, "things": 1, "not": 1, "stupidity": 1} |
||||
{"batman": 3, "stop": 2} |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,79 @@
|
||||
## display_table |
||||
|
||||
### Instructions |
||||
|
||||
- Implement the std::fmt::Display trait for the structure table so the table is printed like in the [Usage](#usage) the length of each column must adjust to the longest element of the column and the element must be centered in the "cell" when possible, if the length of the element doesn't allow to center exactly it must alight slightly to the right. |
||||
|
||||
- Note: If the table is empty `println!` must not print anything. |
||||
|
||||
- Define the associated function `new` that create a new empty table. |
||||
|
||||
- Define the method function `add_row` that adds a new row to the table created from a slice of strings. |
||||
|
||||
### Expected function |
||||
|
||||
```rust |
||||
pub struct Table { |
||||
pub headers: Vec<String>, |
||||
pub body: Vec<Vec<String>>, |
||||
} |
||||
|
||||
impl fmt::Display for Table { |
||||
} |
||||
|
||||
impl Table { |
||||
pub fn new() -> Table { |
||||
} |
||||
|
||||
pub fn add_row(&mut self, row: &[String]) { |
||||
} |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible test for your function: |
||||
|
||||
```rust |
||||
fn main() { |
||||
let mut table = Table::new(); |
||||
println!("{}", table); |
||||
table.headers = vec![ |
||||
String::from("Model"), |
||||
String::from("Piece N°"), |
||||
String::from("In Stock"), |
||||
String::from("Description"), |
||||
]; |
||||
table.add_row(&[ |
||||
String::from("model 1"), |
||||
String::from("43-EWQE304"), |
||||
String::from("30"), |
||||
String::from("Piece for x"), |
||||
]); |
||||
table.add_row(&[ |
||||
String::from("model 2"), |
||||
String::from("98-QCVX5433"), |
||||
String::from("100000000"), |
||||
String::from("-"), |
||||
]); |
||||
table.add_row(&[ |
||||
String::from("model y"), |
||||
String::from("78-NMNH"), |
||||
String::from("60"), |
||||
String::from("nothing"), |
||||
]); |
||||
println!("{}", table); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
| Model | Piece N° | In Stock | Description | |
||||
|---------+-------------+-----------+-------------| |
||||
| model 1 | 43-EWQE304 | 30 | Piece for x | |
||||
| model 2 | 98-QCVX5433 | 100000000 | - | |
||||
| model y | 78-NMNH | 60 | nothing | |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,49 @@
|
||||
## easy_traits |
||||
|
||||
### Instructions |
||||
|
||||
Your task is to implement the trait `AppendStr` for the type String, and `AppendVec` for a vector of strings. |
||||
|
||||
The trait `AppendStr` has only one function, which is appending `"world"` to any object implementing this trait. |
||||
And `AppendVec` will append `"three"` to a vector of strings. |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
trait AppendStr { |
||||
fn append_str(self) -> Self; |
||||
} |
||||
|
||||
trait AppendVec { |
||||
fn append_vec(&mut self) -> Self; |
||||
} |
||||
|
||||
impl AppendStr for String {} |
||||
|
||||
impl AppendVec for Vec<String> {} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function. |
||||
|
||||
```rust |
||||
use easy_traits::easy_traits; |
||||
|
||||
fn main() { |
||||
let s = String::from("hello ").append_str(); |
||||
println!("{}", s); |
||||
|
||||
let l = vec![String::from("one"), String::from("two")].append_vec(); |
||||
println!("{:?}", l); |
||||
} |
||||
``` |
||||
|
||||
And its output |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
hello world |
||||
["one", "two", "three"] |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,85 @@
|
||||
## filter_table |
||||
|
||||
### Instructions |
||||
|
||||
- Define the functions: |
||||
|
||||
- new: creates a new empty table. |
||||
|
||||
- add_rows: adds a new row to the table from a slice of strings. |
||||
|
||||
- filter_cols: that receives a closure that receives a `&str` and returns a `bool` value: |
||||
|
||||
- filter_cols returns a table with all the columns that yielded true when applied to the header. |
||||
|
||||
- filter_rows: that receives a closure that receives a `&str` and returns a `bool` value |
||||
|
||||
- filter_rows returns a table with all the columns that yielded true when applied to the elements of the selected column. |
||||
|
||||
### Expected function |
||||
|
||||
```rust |
||||
pub struct Table { |
||||
pub headers: Vec<String>, |
||||
pub body: Vec<Vec<String>>, |
||||
} |
||||
|
||||
impl Table { |
||||
pub fn new() -> Table { |
||||
} |
||||
|
||||
pub fn add_row(&mut self, row: &[String]) { |
||||
} |
||||
|
||||
pub fn filter_col(&self, filter: ) -> Option<Self> { |
||||
|
||||
} |
||||
|
||||
pub fn filter_row(&self, col_name: &str, filter: ) -> Option<Self> { |
||||
} |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible test for your function: |
||||
|
||||
```rust |
||||
fn main() { |
||||
let mut table = Table::new(); |
||||
table.headers = vec![ |
||||
"Name".to_string(), |
||||
"Last Name".to_string(), |
||||
"ID Number".to_string(), |
||||
]; |
||||
table.add_row(&[ |
||||
"Adam".to_string(), |
||||
"Philips".to_string(), |
||||
"123456789".to_string(), |
||||
]); |
||||
table.add_row(&[ |
||||
"Adamaris".to_string(), |
||||
"Shelby".to_string(), |
||||
"1111123456789".to_string(), |
||||
]); |
||||
table.add_row(&[ |
||||
"Ackerley".to_string(), |
||||
"Philips".to_string(), |
||||
"123456789".to_string(), |
||||
]); |
||||
let filter_names = |col: &str| col == "Name"; |
||||
println!("{:?}", table.filter_col(filter_names)); |
||||
|
||||
let filter_philips = |lastname: &str| lastname == "Philips"; |
||||
println!("{:?}", table.filter_row("Last Name", filter_philips)); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
Some(Table { headers: ["Name"], body: [["Adam"], ["Adamaris"], ["Ackerley"]] }) |
||||
Some(Table { headers: ["Name", "Last Name", "ID Number"], body: [["Adam", "Philips", "123456789"], ["Ackerley", "Philips", "123456789"]] }) |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,43 @@
|
||||
## flat_rust |
||||
|
||||
### Instructions |
||||
|
||||
- Define the functions `flatten_tree` that receives a std::collections::BTreeSet and returns a new `Vec` with the elements in the binary tree in order. |
||||
|
||||
### Expected function |
||||
|
||||
```rust |
||||
pub fn flatten_tree<T: ToOwned<Owned = T>>(tree: &BTreeSet<T>) -> Vec<T> { |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible test for your function: |
||||
|
||||
```rust |
||||
fn main() { |
||||
let mut tree = BTreeSet::new(); |
||||
tree.insert(34); |
||||
tree.insert(0); |
||||
tree.insert(9); |
||||
tree.insert(30); |
||||
println!("{:?}", flatten_tree(&tree)); |
||||
|
||||
let mut tree = BTreeSet::new(); |
||||
tree.insert("Slow"); |
||||
tree.insert("kill"); |
||||
tree.insert("will"); |
||||
tree.insert("Horses"); |
||||
println!("{:?}", flatten_tree(&tree)); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
[0, 9, 30, 34] |
||||
["Horses", "Slow", "kill", "will"] |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
After Width: | Height: | Size: 66 KiB |
@ -0,0 +1,56 @@
|
||||
## insertion_sort |
||||
|
||||
### Instructions |
||||
|
||||
The insertion sort algorithm: |
||||
|
||||
- To sort an array of size n in ascending order: |
||||
|
||||
1. Iterate from slice[1] to slice[n] over the slice. |
||||
|
||||
2. Compare the current element (key) to its predecessor. |
||||
|
||||
3. If the key element is smaller than its predecessor, compare it to the elements before. Move the greater elements one position up to make space for the swapped element. |
||||
|
||||
Here is a visual example of sorting a slice step by step using the insertion sort algorithm. |
||||
|
||||
![](Insertion-Sort-demo.jpg) |
||||
**Figure 1** - Step by step execution of the algorithm insertion sort |
||||
|
||||
- Implement the algorithm insertion sort by creating a function `insertion_sort(slice, steps)` that executes the iterations of the algorithm the number of steps indicated by the parameter `steps`. See the [Usage](#usage) for more information. |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
pub fn insertion_sort(slice: &mut [i32], steps: usize) { |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible program to test your function |
||||
|
||||
```rust |
||||
fn main() { |
||||
let mut target = [5, 3, 7, 2, 1, 6, 8, 4]; |
||||
// executes the first iteration of the algorithm |
||||
insertion_sort(&mut target, 1); |
||||
println!("{:?}", target); |
||||
|
||||
let mut target = [5, 3, 7, 2, 1, 6, 8, 4]; |
||||
let len = target.len(); |
||||
// executes len - 1 iterations of the algorithm |
||||
// i.e. sorts the slice |
||||
insertion_sort(&mut target, len - 1); |
||||
println!("{:?}", target); |
||||
} |
||||
``` |
||||
|
||||
And it's output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
[3, 5, 7, 2, 1, 6, 8, 4] |
||||
[1, 2, 3, 4, 5, 6, 7, 8] |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,83 @@
|
||||
## jumpo |
||||
|
||||
In this project, you will have to create a 2D sidescroller game. You will be using for the first time an external SDK to compile your game: the Android SDK Tool for Unreal Engine, which allows you to create a [.apk file](https://fileinfo.com/extension/apk) that can be installed and played on any Android devices. |
||||
|
||||
### Objectives |
||||
|
||||
In this game for Android, the player will control a character in a similar game than the Google Chrome Running Dinosaur but with coins or gems. So the game will have buttons on screen and that will be bound to character actions like jumping, ducking, etc... Another goal of this project is the sprite and [flipbook](https://docs.unrealengine.com/en-US/AnimatingObjects/Paper2D/Flipbooks/index.html) creation that is used to animate 2D art. |
||||
|
||||
The basic assets you will need for this project can be found in the ["Jumpo.zip"](https://assets.01-edu.org/Unreal-Engine-Projects/Jumpo/Jumpo.zip) file. |
||||
|
||||
### Instructions |
||||
|
||||
The following are the requirements for this project: |
||||
|
||||
- This game should have a main menu that must have a: |
||||
|
||||
- Start button, that loads the game. |
||||
- Stats button, that shows you how many coins you have collected overall, how many times you died, the number of games done and the highest score. You can add more information if you want to. |
||||
- Leaderboard button, that shows the 5 highest scores ever made. |
||||
- Credits button, that shows the names of the developers that worked on the project. |
||||
- Character button, that shows the locked and unlocked characters. |
||||
- Quit button, that closes the app. |
||||
|
||||
#### Map |
||||
|
||||
These are the requirements regarding the game map: |
||||
|
||||
- Create a 2D map with obstacles that the player has to dodge by jumping or ducking. |
||||
- No 3D objects are allowed in any scene of the game. |
||||
- The game is meant to be played in landscape mode. |
||||
|
||||
#### Character and Gameplay |
||||
|
||||
For the character these are the requisites: |
||||
|
||||
- You are free to choose which character you want to use in your game. You can use the resource ones or you can check [this website](https://www.spriters-resource.com/) for more characters and sprites. |
||||
- The character should be "running" from left to right, so the character must be headed right. |
||||
- The character should actually be static in relation to the background and only the background is moving from right to left, giving the illusion that the character is the one moving. |
||||
- Once a part of the background is out of sight, it gets destroyed or moved to the right. |
||||
- If the character does not die, the map should be infinite. |
||||
- Each action (running, jumping, ducking and dying) should play a different animation (a different flipbook). |
||||
- Use the .png or .tga files to extract and create a flipbook. |
||||
- While running, obstacles should appear on the character path. |
||||
- The character can either jump or roll under obstacles to survive. |
||||
- When the character hits an obstacle, it dies and the die flipbook animation gets played. |
||||
- When the character dies, a score screen is displayed and the player needs to enter 3 characters to save his score in the Leaderboard (a sort of nickname). |
||||
- The more time the character survives, the more points he earns. |
||||
- The character can collect coins/gems to load an invincibility bar. |
||||
- The number of coins collected during that run should appear on the screen as well as the progress of the invincibility bar. |
||||
- Once the invincibility bar is loaded up, the player can press it and the character becomes invincible for a short period of time. |
||||
- When the invincibility bar gets emptied, the character comes back to normal. |
||||
- The jump and roll button should be accessible using thumbs when holding the phone (in the lower corners). |
||||
- During the game, the highest ever score should appear on the top middle of the screen and the current score right below it. |
||||
- A pause button should appear somewhere on the screen but should not disturb the player experience. The top right corner is a good place for it. |
||||
- When the player presses the pause button or when the character dies, three buttons should appear: |
||||
- Retry -> Restarts the game and all progress is lost if the game is in pause. |
||||
- Menu -> Goes back to the main menu and all progress is lost if the game is in pause. |
||||
- Quit -> Quits the entire app. |
||||
|
||||
#### Other Game Features |
||||
|
||||
In addition to the requirements of the map and the character, these are other aspects that need to be taken into account: |
||||
|
||||
- When closing the app and launching it again, all the player data should remain as he leaved it before. |
||||
|
||||
On the main menu: |
||||
|
||||
- On the "Character" tab, the player sees grayed-out characters. These are the locked characters. |
||||
- This characters can be unlocked by spending coins/gems collected. |
||||
- When first opening the game, there should be only one character unlocked. |
||||
- When a player dies, the Leaderboard should be updated accordingly to the score the player just made if it is on the 5 best score ever. |
||||
- Also the Stats should be updated after every game, whether it is or it is not one of the best 5 scores ever. |
||||
- On the Leaderboard and on the Stats tabs, a button to reset all the stats should be available. |
||||
|
||||
#### Android |
||||
|
||||
In order to complete this project you are going to need to run your game in Android devices. For that you will need to install an Android SDK. Here is the Unreal Engine [documentation](https://docs.unrealengine.com/en-US/SharingAndReleasing/Mobile/Android/Setup/AndroidStudio/index.html) for that and a [video](https://www.youtube.com/watch?v=q-mAEnqZb0M) that could also help you. |
||||
|
||||
- You could use your own android device or you could use an emulator to install the app on it and run the app to confirm that everything is working properly on Android devices. |
||||
|
||||
### Hints |
||||
|
||||
If you want a good example of how a 2D game is created you can try the [Tappy Chicken](https://assets.01-edu.org/Unreal-Engine-Projects/Jumpo/TappyChicken.zip) game provided. Or you can create an empty project and choose "2D Sidescroller Game" template which contains a lot of info that will be helpful for this project. |
@ -0,0 +1,77 @@
|
||||
#### Functional |
||||
|
||||
###### Is a main menu displayed at the game startup offering 5 options? |
||||
|
||||
###### Does the Credits button show you the names of the developers that worked on the project? |
||||
|
||||
###### Does the Quit button make the player quit the game? |
||||
|
||||
###### Does the Start button on the main menu start a new game? |
||||
|
||||
###### Does the Character button show you the unlockable characters and the price to unlock them? |
||||
|
||||
###### Does the Leaderboard button show the 5 best scores? |
||||
|
||||
###### Does the Stats button show the games stats (amount of coins you have collected overall, how many times you died, number of games and highest score)? |
||||
|
||||
###### Does the map contain obstacles that the player has to dodge? |
||||
|
||||
###### Can you confirm that there is no 3D objects in the game? |
||||
|
||||
###### Is the game meant to be played in landscape mode? |
||||
|
||||
###### Is the player heading on the right side? |
||||
|
||||
###### Is the background moving from right to left, giving the illusion that the player is the one moving? |
||||
|
||||
###### Is the map infinite if the character does not hit anything? |
||||
|
||||
###### Does each action (running, jumping, ducking and dying) play a different flipbook? |
||||
|
||||
###### When the character hits an obstacle does he die? |
||||
|
||||
###### When the character dies, is a score screen displayed, and the player needs to enter 3 characters to save his score in the Leaderboard? |
||||
|
||||
###### If the score of the player is one of the best 5 scores ever, does the Leaderboard gets updated? |
||||
|
||||
###### Can the character collect coins/gems? |
||||
|
||||
###### Does the invincibility bar fill up when collecting coins/gems? |
||||
|
||||
###### Does the character becomes invincible for a little while once the player touch the invincibility bar? |
||||
|
||||
###### When the invincibility bar gets emptied, does the character come back to normal? |
||||
|
||||
###### Are the jump and duck/roll button accessible using thumbs when holding the phone? |
||||
|
||||
###### Can the character jump and duck/roll when touching the buttons? |
||||
|
||||
###### Are the highest score and current score displayed on the top middle of the screen while playing? |
||||
|
||||
###### Is the current score being updated as you play? |
||||
|
||||
###### Is a pause button available to the player? |
||||
|
||||
###### Does the Retry button on the pause menu start a new game, losing the previous progress made? |
||||
|
||||
###### Does the Menu button on the pause menu take the player to the main menu, losing the previous progress made? |
||||
|
||||
###### When pressing the pause button, does the game stop on the background and the retry, menu, and quit button appear on screen? |
||||
|
||||
###### Does the Quit button on the pause menu, quit the entire app? |
||||
|
||||
###### When quitting the app and turning back, does the Stats and Leaderboard menu still contain data? |
||||
|
||||
###### If in the Leaderboard or Stats menu you press the reset button, is all the data reset to 0? |
||||
|
||||
###### Is the apk built using the latest Android SDK version? |
||||
|
||||
#### Bonus |
||||
|
||||
###### Can the player buy an extra life before the start of the game using coins/gems? |
||||
|
||||
###### Are different sprites being used from the ones provided? |
||||
|
||||
###### Are there different map backgrounds? |
||||
|
||||
###### Can the coins/gems be used in an in-game store to buy skins or perks? |
@ -0,0 +1,36 @@
|
||||
## lastup |
||||
|
||||
### Instructions |
||||
|
||||
Complete the `lastup` function that takes a string and puts the last letter of each word in uppercase and the rest in lowercase. |
||||
|
||||
### Expected Functions |
||||
|
||||
```rust |
||||
pub fn lastup(input: &str) -> String { |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function. |
||||
|
||||
```rust |
||||
use lastup::lastup; |
||||
|
||||
fn main() { |
||||
println!("{}", lastup("joe is missing")); |
||||
println!("{}", lastup("jill is leaving A")); |
||||
println!("{}",lastup("heLLo THere!")); |
||||
} |
||||
``` |
||||
|
||||
And its output |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
joE iS missinG |
||||
jilL iS leavinG A |
||||
hellO therE! |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,56 @@
|
||||
## matrix_determinant |
||||
|
||||
### Instructions |
||||
|
||||
Write a matrix_determinant function that receives a 3x3 matrix ([[isize; 3]; 3]) and returns its determinant (isize). |
||||
|
||||
This is how you calculate a 2x2 matrix determinant: |
||||
|
||||
```sh |
||||
|a b| |
||||
|c d| |
||||
|
||||
a*d - b*c |
||||
``` |
||||
|
||||
To calculate a 3x3 matrix determinant (below) you have to take 'a' and multiply it by the determinant of the matrix you get if you get rid of 'a' column and row. Then you subtract the multiplication of 'b' and the determinant of the matrix you get if you get rid of 'b' column and row. And finally, you do the same process for 'c' and add it to the previous result. |
||||
|
||||
```sh |
||||
|a b c| |
||||
|d e f| |
||||
|g h i| |
||||
``` |
||||
|
||||
### Expected Function |
||||
|
||||
```rs |
||||
pub fn matrix_determinant(matrix: [[isize; 3]; 3]) -> isize { |
||||
|
||||
} |
||||
``` |
||||
|
||||
### Example |
||||
|
||||
Here is a program to test your function: |
||||
|
||||
```rs |
||||
fn main() { |
||||
let matrix = [[1, 2, 4], [2, -1, 3], [4, 0, 1]]; |
||||
|
||||
println!( |
||||
"The determinant of the matrix:\n|1 2 4|\n|2 -1 3| = {}\n|4 0 1|", |
||||
matrix_determinant(matr) |
||||
); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```sh |
||||
$ cargo run |
||||
The determinant of the matrix: |
||||
|1 2 4| |
||||
|2 -1 3| = 35 |
||||
|4 0 1| |
||||
$ |
||||
``` |
@ -0,0 +1,44 @@
|
||||
## matrix_display |
||||
|
||||
### Instructions |
||||
|
||||
Use the Matrix struct given in the [expected struct](#expected-functions-and-struct) and implement the `std::fmt::Display` trait so it prints the matrix like in the [usage](#usage). |
||||
|
||||
You will also have to implement the associated function `new` that creates a matrix from a slice of slices. |
||||
|
||||
### Expected Functions and Struct |
||||
|
||||
```rust |
||||
pub struct Matrix(pub Vec<Vec<i32>>); |
||||
|
||||
pub fn new(slice: &[&[i32]]) -> Self { |
||||
} |
||||
|
||||
use std::fmt; |
||||
|
||||
impl fmt::Display for Matrix { |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible program to test your function |
||||
|
||||
```rust |
||||
use matrix_display::*; |
||||
|
||||
fn main() { |
||||
let matrix = Matrix::new(&[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]]); |
||||
println!("{}", matrix); |
||||
} |
||||
``` |
||||
|
||||
And it's output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
(1 2 3) |
||||
(4 5 6) |
||||
(7 8 9) |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,69 @@
|
||||
## matrix_transposition_4by3 |
||||
|
||||
### Instructions |
||||
|
||||
- Define the structure matrix as a tuple of tuples of `i32`'s |
||||
|
||||
- Define a function that calculate the transpose matrix of a 4x3 matrix (4 rows by 3 columns) which is a 3x4 matrix (3 rows by 4 columns). |
||||
|
||||
- Note: |
||||
|
||||
- The transpose of a matrix `A` is the matrix `A'` where `A'`'s columns are `A`'s row and the rows are the columns: |
||||
|
||||
Example: |
||||
|
||||
``` |
||||
( a b c ) __ transposition __> ( a d g j ) |
||||
( d e f ) ( b e h k ) |
||||
( g h i ) ( c f i l ) |
||||
( j k l ) |
||||
``` |
||||
|
||||
- Matrix must implement Debug, PartialEq and Eq. You can use derive |
||||
|
||||
- Remember that you're defining a library so you have to make public the elements that are going to be called from an external crate. |
||||
|
||||
### Notions |
||||
|
||||
[Chapter 7]( https://doc.rust-lang.org/stable/book/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html ) |
||||
|
||||
### Expected Function and Structs |
||||
|
||||
```rust |
||||
pub struct Matrix4by3( |
||||
pub (i32, i32, i32), |
||||
pub (i32, i32, i32), |
||||
pub (i32, i32, i32), |
||||
pub (i32, i32, i32), |
||||
); |
||||
|
||||
pub struct Matrix3by4( |
||||
pub (i32, i32, i32, i32), |
||||
pub (i32, i32, i32, i32), |
||||
pub (i32, i32, i32, i32), |
||||
); |
||||
|
||||
pub fn transpose(m: Matrix4by3) -> Matrix3by4 { |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a posible program to test your function |
||||
|
||||
```rust |
||||
fn main() { |
||||
let matrix = Matrix4by3((1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12)); |
||||
println!("Original matrix {:?}", matrix); |
||||
println!("Transpose matrix {:?}", transpose(matrix)); |
||||
} |
||||
``` |
||||
|
||||
And it's output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
Original matrix Matrix4by3((1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12)) |
||||
Transpose matrix Matrix3by4((1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)) |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,37 @@
|
||||
## nextprime |
||||
|
||||
### Instructions |
||||
|
||||
Write a function that returns the first prime number that is equal or superior to the `int` passed as parameter. |
||||
|
||||
The function must be optimized in order to avoid time-outs with the tester. |
||||
|
||||
(We consider that only positive numbers can be prime numbers) |
||||
|
||||
### Expected function |
||||
|
||||
```rust |
||||
pub fn next_prime(nbr: u64) -> u64 { |
||||
|
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible program to test your function : |
||||
|
||||
```rust |
||||
fn main() { |
||||
println!("The next prime after 4 is: {}", next_prime(4)); |
||||
println!("The next prime after 11 is: {}", next_prime(11)); |
||||
} |
||||
``` |
||||
|
||||
And its output : |
||||
|
||||
```console |
||||
$ cargo run |
||||
The next prime after 4 is: 5 |
||||
The next prime after 11 is: 11 |
||||
$ |
||||
``` |
@ -0,0 +1,91 @@
|
||||
## order_books |
||||
|
||||
### Instructions |
||||
|
||||
Build a module called `library` with two sub-modules inside it: |
||||
|
||||
- `writers` which contains a structure called `Writer` that has a first_name (String), last_name (String) and a set of books (Vec\<Book\>). |
||||
- `books` which contains a structure called `Book` that has a title (String) and a year of publish (u64). |
||||
|
||||
You will also have to create (outside the previous modules) a function `order_books` that receives a writer (Writer) and orders the set of books alphabetically. |
||||
|
||||
### Expected Functions and Structs |
||||
|
||||
```rs |
||||
pub fn order_books(writer: &mut Writer) { |
||||
|
||||
} |
||||
``` |
||||
|
||||
```rs |
||||
struct Writer { |
||||
|
||||
} |
||||
``` |
||||
|
||||
```rs |
||||
struct Book { |
||||
|
||||
} |
||||
``` |
||||
|
||||
### Example |
||||
|
||||
Here is a program to test your function and structs: |
||||
|
||||
```rs |
||||
fn main() { |
||||
let mut writer_a = Writer { |
||||
first_name: "William".to_string(), |
||||
last_name: "Shakespeare".to_string(), |
||||
books: vec![ |
||||
Book { |
||||
title: "Hamlet".to_string(), |
||||
year: 1600, |
||||
}, |
||||
Book { |
||||
title: "Othelo".to_string(), |
||||
year: 1603, |
||||
}, |
||||
Book { |
||||
title: "Romeo and Juliet".to_string(), |
||||
year: 1593, |
||||
}, |
||||
Book { |
||||
title: "MacBeth".to_string(), |
||||
year: 1605, |
||||
}, |
||||
], |
||||
}; |
||||
|
||||
println!("Before ordering"); |
||||
for b in &writer_a.books { |
||||
println!("{:?}", b.title); |
||||
} |
||||
|
||||
order_books(&mut writer_a); |
||||
|
||||
println!("\nAfter ordering"); |
||||
for b in writer_a.books { |
||||
println!("{:?}", b.title); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```sh |
||||
$ cargo run |
||||
Before ordering |
||||
"Hamlet" |
||||
"Othelo" |
||||
"Romeo and Juliet" |
||||
"MacBeth" |
||||
|
||||
After ordering |
||||
"Hamlet" |
||||
"MacBeth" |
||||
"Othelo" |
||||
"Romeo and Juliet" |
||||
$ |
||||
``` |
@ -0,0 +1,67 @@
|
||||
## partial_sums |
||||
|
||||
### Instructions |
||||
|
||||
Write a `partial_sums` function that receives a reference of an array of u64 and returns a vector with the partial sums of the received array. |
||||
|
||||
This is how partial sums work: |
||||
|
||||
1- First you split the array in its partitions: |
||||
|
||||
```sh |
||||
[1, 2, 3, 4, 5] |
||||
| |
||||
V |
||||
[1, 2, 3, 4, 5] |
||||
[1, 2, 3, 4] |
||||
[1, 2, 3] |
||||
[1, 2] |
||||
[1] |
||||
[] |
||||
``` |
||||
|
||||
2- Then you add each partition together: |
||||
|
||||
```sh |
||||
[1, 2, 3, 4, 5] = 15 |
||||
[1, 2, 3, 4] = 10 |
||||
[1, 2, 3] = 6 |
||||
[1, 2] = 3 |
||||
[1] = 1 |
||||
[] = 0 |
||||
``` |
||||
|
||||
3- So, in conclusion: |
||||
|
||||
```rs |
||||
partial_sums(&[1, 2, 3, 4, 5]) // == [15, 10, 6, 3 ,1, 0] |
||||
``` |
||||
|
||||
### Expected Result |
||||
|
||||
```rs |
||||
pub fn matrix_determinant(arr: &[u64]) -> Vec<64>{ |
||||
|
||||
} |
||||
``` |
||||
|
||||
### Example |
||||
|
||||
Here is a program to test your function: |
||||
|
||||
```rs |
||||
fn main() { |
||||
println!( |
||||
"Partial sums of [5, 18, 3, 23] is : {:?}", |
||||
parts_sums(&[5, 18, 3, 23]) |
||||
); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```sh |
||||
$ cargo run |
||||
Partial sums of [5, 18, 3, 23] is : [49, 26, 23, 5, 0] |
||||
$ |
||||
``` |
@ -0,0 +1,33 @@
|
||||
## prev_prime |
||||
|
||||
### Instructions |
||||
|
||||
Write a function that returns the first prime number that is equal or inferior to the `int` passed as parameter. |
||||
|
||||
If there are no primes inferior to the `int` passed as parameter the function should return 0. |
||||
|
||||
### Expected function |
||||
|
||||
```rust |
||||
pub fn prev_prime(nbr: u64) -> u64 { |
||||
|
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible [program](TODO-LINK) to test your function : |
||||
|
||||
```rust |
||||
fn main() { |
||||
println!("The previous prime number before 34 is: {}", prev_prime(34)); |
||||
} |
||||
``` |
||||
|
||||
And its output : |
||||
|
||||
```console |
||||
$ cargo run |
||||
The previous prime number before 34 is: 31 |
||||
$ |
||||
``` |
@ -0,0 +1,92 @@
|
||||
## queens |
||||
|
||||
### Instructions |
||||
|
||||
In a chess game, a queen can attack pieces which are on the same row, |
||||
column, or diagonal. |
||||
|
||||
Your purpose in this exercise is to find out if two queens can attack |
||||
each other using the same rules. |
||||
|
||||
The chess board will be represented as an 8 by 8 array. |
||||
|
||||
So, given the position of the two queens on a chess board, you will have to |
||||
implement the function `can_attack` in the given struct `Queen` with |
||||
the purpose of finding out if the two queens can attack each other or not. |
||||
|
||||
For this to be possible, you will also have to implement the struct `ChessPosition` |
||||
with the function `new` that will allow you to verify if the position is valid or not. If the position is valid it will return that position and if it is invalid it will return `None`. |
||||
|
||||
So if you are told that the white queen is at (2, 3) and the black queen is at (5, 6), |
||||
then you would know you have got a set-up like so: |
||||
|
||||
``` |
||||
_ _ _ _ _ _ _ _ |
||||
_ _ _ _ _ _ _ _ |
||||
_ _ _ W _ _ _ _ |
||||
_ _ _ _ _ _ _ _ |
||||
_ _ _ _ _ _ _ _ |
||||
_ _ _ _ _ _ B _ |
||||
_ _ _ _ _ _ _ _ |
||||
_ _ _ _ _ _ _ _ |
||||
``` |
||||
|
||||
In this case, the two queens can attack each other because both pieces share a diagonal. |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
#[derive(Debug)] |
||||
pub struct ChessPosition { |
||||
rank: i32, |
||||
file: i32, |
||||
} |
||||
|
||||
#[derive(Debug)] |
||||
pub struct Queen { |
||||
position: ChessPosition, |
||||
} |
||||
|
||||
impl ChessPosition { |
||||
pub fn new(rank: i32, file: i32) -> Option<Self> {} |
||||
} |
||||
|
||||
impl Queen { |
||||
pub fn can_attack(&self, other: &Queen) -> bool {} |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a possible program to test your function : |
||||
|
||||
```rust |
||||
use queens::queens; |
||||
|
||||
fn main() { |
||||
let white_queen = Queen::new(ChessPosition::new(2, 2).unwrap()); |
||||
let black_queen = Queen::new(ChessPosition::new(0, 4).unwrap()); |
||||
|
||||
println!( |
||||
"Is it possible for the queens to attack each other? => {}", |
||||
white_queen.can_attack(&black_queen) |
||||
); |
||||
|
||||
let white_queen = Queen::new(ChessPosition::new(1, 2).unwrap()); |
||||
let black_queen = Queen::new(ChessPosition::new(0, 4).unwrap()); |
||||
|
||||
println!( |
||||
"Is it possible for the queens to attack each other? => {}", |
||||
white_queen.can_attack(&black_queen) |
||||
); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
Is it possible for the queens to attack each other? => true |
||||
Is it possible for the queens to attack each other? => false |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,45 @@
|
||||
## rot21 |
||||
|
||||
### Instructions |
||||
|
||||
Your purpose in this exercise is to create a `rot21` function that works like the ROT13 cipher. |
||||
|
||||
Your function will receive a string and it will rotate each letter of that string 21 times to the right. |
||||
|
||||
Your function should only change letters. If the string includes punctuation, symbols and numbers |
||||
they will remain the same. |
||||
|
||||
### Expected functions |
||||
|
||||
```rust |
||||
pub fn rot21(input: &str) -> String {} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function. |
||||
|
||||
```rust |
||||
use rot21::rot21; |
||||
|
||||
fn main() { |
||||
println!("The letter \"a\" becomes: {}", rot21("a")); |
||||
println!("The letter \"m\" becomes: {}", rot21("m")); |
||||
println!("The word \"MISS\" becomes: {}", rot21("MISS")); |
||||
println!("Your cypher wil be: {}", rot21("Testing numbers 1 2 3")); |
||||
println!("Your cypher wil be: {}", rot21("rot21 works!")); |
||||
} |
||||
|
||||
``` |
||||
|
||||
And its output |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
The letter "a" becomes: v |
||||
The letter "m" becomes: h |
||||
The word "MISS" becomes: HDNN |
||||
Your cypher wil be: Oznodib iphwzmn 1 2 3 |
||||
Your cypher wil be: mjo21 rjmfn! |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
@ -0,0 +1,73 @@
|
||||
## rpn |
||||
|
||||
### Instructions |
||||
|
||||
Write a program that takes a `string` which contains an equation written in |
||||
`Reverse Polish Notation` (RPN) as its first argument, that evaluates the equation, and that |
||||
prints the result on the standard output followed by a newline (`'\n'`). |
||||
|
||||
`Reverse Polish Notation` is a mathematical notation in which every operator |
||||
follows all of its operands. In RPN, every operator encountered evaluates the |
||||
previous 2 operands, and the result of this operation then becomes the first of |
||||
the two operands for the subsequent operator. Operands and operators must be |
||||
spaced by at least one space. |
||||
|
||||
The following operators must be implemented : `+`, `-`, `*`, `/`, and `%`. |
||||
|
||||
If the `string` is not valid or if there is not exactly one argument, `Error` must be printed |
||||
on the standard output followed by a newline. |
||||
If the `string` has extra spaces it is still considered valid. |
||||
|
||||
All the given operands must fit in a `int`. |
||||
|
||||
Examples of formulas converted in RPN: |
||||
|
||||
3 + 4 >> 3 4 + |
||||
|
||||
((1 \* 2) \* 3) - 4 >> 1 2 \* 3 \* 4 - or 3 1 2 \* \* 4 - |
||||
|
||||
50 \* (5 - (10 / 9)) >> 5 10 9 / - 50 \* |
||||
|
||||
Here is how to evaluate a formula in RPN: |
||||
|
||||
``` |
||||
1 2 * 3 * 4 - |
||||
2 3 * 4 - |
||||
6 4 - |
||||
2 |
||||
``` |
||||
|
||||
Or: |
||||
|
||||
``` |
||||
3 1 2 * * 4 - |
||||
3 2 * 4 - |
||||
6 4 - |
||||
2 |
||||
``` |
||||
|
||||
For receiving arguments from the command line you should use something like: |
||||
|
||||
```rust |
||||
fn main() { |
||||
let args: Vec<String> = std::env::args().collect(); |
||||
|
||||
rpn(&args[1]); |
||||
} |
||||
|
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
````console |
||||
$ cargo run "1 2 * 3 * 4 +" |
||||
10 |
||||
$ cargo run "1 2 3 4 +" |
||||
Error |
||||
$ cargo run |
||||
Error |
||||
$ cargo run " 1 3 * 2 -" |
||||
1 |
||||
$ cargo run " 1 3 * ksd 2 -" |
||||
Error``` |
||||
```` |
@ -1,58 +1,64 @@
|
||||
## Scaler |
||||
## Scalar |
||||
|
||||
### Instructions |
||||
Create the following functions, that receives two parameters: |
||||
- sum, that returns the sum between two values from 0 to 255 |
||||
- diff, that returns the difference between two values from -32768 to 32767 |
||||
- pro, that returns the product of the multiplication between two values from -128 to 127 |
||||
- quo, that returns the quotient of the division between two values |
||||
- rem, that returns the remainder of the division between two values |
||||
Create the following **functions**, which each receives two parameters: |
||||
- `sum`, which returns the sum between two values from 0 to 255 |
||||
- `diff`, which returns the difference between two values from -32768 to 32767 |
||||
- `pro`, which returns the product of the multiplication between two values from -128 to 127 |
||||
- `quo`, which returns the quotient of the division between two values (32bit and you have to figure out the second part) |
||||
- `rem`, which returns the remainder of the division between two values (32bit and you have to figure out the second part) |
||||
|
||||
You **must** complete the Expected functions parameters data type accordingly (Replace the Xs)! |
||||
|
||||
### Notions |
||||
- https://doc.rust-lang.org/book/ch03-02-data-types.html |
||||
- [Data Types](https://doc.rust-lang.org/book/ch03-02-data-types.html) |
||||
|
||||
|
||||
### Expected functions |
||||
### Expected functions (Incomplete, you must precise the Data Types) |
||||
|
||||
```rust |
||||
pub fn sum(a:, b: ) -> { |
||||
pub fn sum(a: X , b: X) -> X { |
||||
|
||||
} |
||||
|
||||
pub fn diff(a: , b: ) -> { |
||||
pub fn diff(a: X, b: X) -> X { |
||||
|
||||
} |
||||
|
||||
pub fn pro(a: , b: ) -> { |
||||
pub fn pro(a: X, b: X) -> X { |
||||
|
||||
} |
||||
|
||||
pub fn quo(a: , b: ) -> { |
||||
pub fn quo(a: X, b: X) -> X { |
||||
|
||||
} |
||||
|
||||
pub fn rem(a: , b: ) -> { |
||||
pub fn rem(a: X, b: X) -> X { |
||||
|
||||
} |
||||
``` |
||||
|
||||
### Usage: |
||||
### Usage : |
||||
#### Note that There is no output for this test for you to train to comment accordingly. |
||||
|
||||
```rust |
||||
use scalar::*; |
||||
|
||||
fn main() { |
||||
// sum |
||||
println!("sum : {}", sum(234, 2)); |
||||
println!("sum : {}", sum(234, 2)); // 'sum : 236' |
||||
println!("sum : {}", sum(1, 255)); // 'ERROR: attempt to add with overflow' |
||||
// diff |
||||
println!("diff : {}", diff(234, 2)); |
||||
println!("diff : {}", diff(234, 2)); // 'diff : 232' |
||||
println!("diff : {}", diff(-32768, 32766)); // 'ERROR: attempt to subtract with overflow' |
||||
// product |
||||
println!("pro : {}", pro(23, 2)); |
||||
println!("pro : {}", pro(23, 2)); // 'pro : 46' |
||||
println!("pro : {}", pro(-128, 2)); // 'ERROR: attempt to multiply with overflow' |
||||
// quotient |
||||
println!("quo : {}", quo(22.0, 2.0)); |
||||
println!("quo : {}", quo(-128.23, 2.0)); |
||||
println!("quo : {}", quo(22.0, 2.0));// 'quo : 11' |
||||
println!("quo : {}", quo(-128.23, 2.0));// 'quo : -64.115' |
||||
// remainder |
||||
println!("rem : {}", rem(22.0, 2.0)); |
||||
println!("rem : {}", rem(-128.23, 2.0)); |
||||
println!("rem : {}", rem(22.0, 2.0));// 'rem : 0' |
||||
println!("rem : {}", rem(-128.23, 2.0));// 'rem : -0.22999573' |
||||
} |
||||
``` |
||||
|
@ -0,0 +1,81 @@
|
||||
## stealth-boom |
||||
|
||||
In this project, you will have to create an entire stealth game using Unreal Engine. |
||||
|
||||
### Objectives |
||||
|
||||
The idea of this project is to create a little 10 minutes gameplay game with missions, with stealth based gameplay and with an AI patrolling NPC. |
||||
|
||||
The basics assets you will need for this project can be found in the [Stealth-Boom.zip](https://assets.01-edu.org/Unreal-Engine-Projects/StealthBoom.zip) file. It contains the basic animations, character, enemies and props you will need for this project. |
||||
|
||||
### Instructions |
||||
|
||||
The following aspects should be fulfilled: |
||||
|
||||
- Create a map where the player can walk around. |
||||
|
||||
- This map should contain places for the player to hide from enemies by crouching, hide behind walls, and all other props you may use to help it make a stealth game. |
||||
- Buildings with at least 2 floors. |
||||
- Pickable ammunition and weapons around the map. |
||||
|
||||
- For the player you should add: |
||||
|
||||
- Walk and run animations |
||||
- Reload animation |
||||
- Aim animation |
||||
- Shoot animation |
||||
- Crouch animation |
||||
- the player should be able to do the above six actions while crouching |
||||
- Melee attack animation |
||||
- Gun sound when firing |
||||
- Bullets visual impact on walls (see decals documentation) |
||||
- Blood particles when hit |
||||
|
||||
- The game should contain a main menu where the player can: |
||||
|
||||
- Start the game |
||||
- Adjust the general sound of the game |
||||
- Change the graphics settings |
||||
- When changing the resolution, a pop-up should appear in the middle of the screen asking if the player wants to keep the graphics setting he/she just applied. If `Yes` is clicked within 10 seconds, the settings are set, otherwise, if the 10 seconds delay is over or if the player clicks `No`, the settings go back to the old ones. |
||||
- Change the mouse sensitivity |
||||
- Invert the mouse vertical axis |
||||
|
||||
- You should have at least 3 types of enemies: `Guards` (who patrol around and are lookig for intruders), `Drones` (same as Guards but which can fly), and `Cameras` (stationary and looking for intruders). More enemies can be added if you want to. |
||||
|
||||
- Guards AI: |
||||
- Guards should be able to patrol around the map; |
||||
- A Guard is able to see the player, if the player crosses his field of view; |
||||
- When the player enters the field of view of a Guard, the Guard enters into chasing mode and must start running after the player, takes cover and shoots at the player. |
||||
- If the player leaves the field of view for a certain time, the Guard goes back to patrol mode. |
||||
- Drones AI: |
||||
- Drones should be able to patrol around the map; |
||||
- A light color should determine the state of the drone (Blue for patrolling, Red for chasing the player); |
||||
- Once the player crosses the drone camera, the drone light turns red and the drone enters chasing mode; |
||||
- When a drone is in chasing mode, all the guards on the area are alerted, and should enter chasing mode as well; |
||||
- When the player is out of the drone sight, the drone turns back to patrol mode; |
||||
- The sight radius should be inferior on the drones that on the guards. |
||||
- Camera AI: |
||||
- Cameras should be placed on walls; |
||||
- Cameras should have the same light sign as the drone, so when the player is in the camera sight, the camera light turns red and all Guards enter in chasing mode; |
||||
- Like the Drones, Cameras warn guards, whenever the player passes through the camera field of view; |
||||
- Some Cameras should lock access of certain areas of the map (for example, close doors) when the player is detected by that camera. |
||||
|
||||
- Drones, Guards and Cameras should have sounds effect whenever they change from chase to patrol mode, as well as the other way around. |
||||
|
||||
- All AI should be implemented using Behavior Trees except for the Camera. |
||||
|
||||
- The player mission is up to you, either it can be some task to fix, kill all guards without getting caught or collect documents... Whatever you choose, the player should have enemies on his way to divert him away from his objective. |
||||
|
||||
- When the player successfully completes his mission, a pop up should appear saying that the mission is completed. |
||||
|
||||
- The player has a health bar that should go down whenever the player gets shot. When the player dies, he has the choice to either quit the game, go back to the main menu or start over. |
||||
|
||||
- If the player starts over, the level should not be reloaded. The player should spawn back to the starting point. |
||||
|
||||
- When pressing `Esc` the game is set on paused and the main menu widget pops up. |
||||
|
||||
- The player should be able to change the game graphics setting exactly like in the main menu. |
||||
|
||||
- A game should not last longer than 6 minutes. After that the same choices should appear as when the player dies. |
||||
|
||||
> Do not forget to zip up the project compile and save everything for peer correction. |
@ -0,0 +1,67 @@
|
||||
#### Functional |
||||
|
||||
###### Does the map contain places for the player to hide from enemies? |
||||
|
||||
###### Does the map contain buildings, pickable ammunition and weapons placed around the map? |
||||
|
||||
###### Does the player have all the minimal animation required (walking, running, melee attacking, aiming, reloading, shooting, crouching, crouch walking, crouch aiming, crouch reloading, crouch shooting)? |
||||
|
||||
###### Is there a sound for the player shooting? |
||||
|
||||
###### Are there bullets impacts present when shooting at a wall? |
||||
|
||||
###### When the player is hit, are there any blood particles? |
||||
|
||||
###### Is a main menu with the five options displayed on the screen? |
||||
|
||||
###### Can the general sound of the game be managed directly on the settings menu? |
||||
|
||||
###### When changing the resolution, does a pop-up get displayed on the screen to confirm the changes we just set? |
||||
|
||||
###### Does pressing “No” on the graphics confirmation pop-up, resets the settings to the old ones? |
||||
|
||||
###### Are the mouse settings (mouse sensitivity, invert mouse vertical axis) functioning according to their descriptions? |
||||
|
||||
###### Do the guards and drones wander around the map? |
||||
|
||||
###### When a player enters the field of view of a guard, does he switches to chasing mode, running and shooting towards the player while also taking cover? |
||||
|
||||
###### Does the drone light switches between each state? Blue for patrolling and red for chase mode (when a player crosses its sight)? |
||||
|
||||
###### Whenever a drone turns to chasing mode, do all the guards in the area get alerted and switch to chasing mode as well? |
||||
|
||||
###### Does the drone come back to patrol mode when the player is out of the drone sight? |
||||
|
||||
###### Is the sight radius of the drones smaller than the guards? |
||||
|
||||
###### Are cameras attached to walls? |
||||
|
||||
###### Do cameras have similar light sign as the drones (red for alert mode and blue for patrol)? |
||||
|
||||
###### As the drones, do the cameras alert guards on the area, switching them to chasing mode? |
||||
|
||||
###### Do Guards, Drones and Cameras play an alert sound when a player gets detected? |
||||
|
||||
###### Do some cameras lock access to certain areas of the map, when they detect a player? |
||||
|
||||
###### Can the camera close some part of the map (thru closed doors, open traps and tries to kill the player etc…) to the player when the player is being detected? |
||||
|
||||
###### Are Behavior Trees used to implement the AI of the Guards and Drones? |
||||
|
||||
###### Does the player have a goal? |
||||
|
||||
###### When the goal of the player is successfully completed, does a pop up appear saying that the mission is completed? |
||||
|
||||
###### Does the player have a health bar? |
||||
|
||||
###### Does the player health decreases when he gets shot by the guards? |
||||
|
||||
###### When the player loses all his health (dies), does he get to choose whether to quit the game, go back to the main menu, or to start over? |
||||
|
||||
###### If the player starts over does he spawn back at the starting point? |
||||
|
||||
###### Is the lifespan of the game at least 6 minutes long from launch to mission completed? |
||||
|
||||
#### Bonus |
||||
|
||||
###### Are there headshots implemented? |
@ -0,0 +1,49 @@
|
||||
## the-pages |
||||
|
||||
In this exercise, one will create a mini-horror game inspired on ["Slender: The Eight Pages"](https://en.wikipedia.org/wiki/Slender:_The_Eight_Pages) game. |
||||
|
||||
### Objectives |
||||
|
||||
Just like in the Slender game, the goal of your game should be, while being chased by a monster/creature (a "Creep"), to get all the 8 pages spread around the map in different locations. |
||||
|
||||
To find models of scary monsters/creatures: |
||||
- you can easily choose checking the [Mixamo website](https://www.mixamo.com/#/). |
||||
|
||||
- alternatively, you can use the models on the ["Creeps.zip"](https://assets.01-edu.org/Unreal-Engine-Projects/ThePages/Creeps.zip) file. |
||||
|
||||
- you can also check in the [assets](https://assets.01-edu.org/Unreal-Engine-Projects/ThePages/ThePages.zip) (basics animations, character, enemies and props) you will need for this project. |
||||
|
||||
### Instructions |
||||
|
||||
On startin, the game should ask the player to press a button to enter the game. Once the player does that, the actual gameplay level should be loaded. |
||||
|
||||
The map for your game should be a large squared landscape terrain, scaled at 10 by 10 units. The action should be happening at night time in a forest-like environment. Your map should contain: |
||||
|
||||
- trees, some little facilities (like shelters or little buildings), monuments etc... You should use the [Foliage Tool](https://docs.unrealengine.com/en-US/BuildingWorlds/Foliage/index.html) to spread trees, rocks and grass around the landscape and to make them have different sizes, scales and rotations. |
||||
- To create buildings, you will be using the built in [BSP](https://www.worldofleveldesign.com/categories/ue4/bsp-01-what-is-bsp.php). This method will allow you to create complex meshes and apply textures to it (Useful when you have no 3D modeling skills). |
||||
- the map should also contain 8 pages spread around it in the facilities or monuments you created, but should be placed in different spots of those locations in each game. |
||||
- the map should have at least three different kind of floor surface: dirt, grass and concrete. |
||||
|
||||
For the creature or monster that you choose to design: |
||||
|
||||
- It can only move (very slowly so it does not catch up to the player that quickly) when it is not within the player field of view. This means if the player sees it, it should stop. |
||||
- Randomly, the "Creep" should teleport to another location. |
||||
- The "Creep" never appears before the player collects at least 1 page on the map. |
||||
- While completing the task of collecting the 8 pages, the monster should randomly disturb our experience by appearing on the player screen, making that task more difficult. |
||||
- When the creep is within the player's sight, a disturbing music/sound must be played and the camera should start stuttering like in the original game. |
||||
|
||||
The player should control a FPS (First Person Shooter) Character that: |
||||
|
||||
- has to collect 8 pages placed around the map. |
||||
- The player can collect the pages by left-clicking on them. |
||||
- A sound should be played when the player collects a page and a text should appear temporarily on screen showing how many pages are missing (example: 5 / 8 Pages). |
||||
- can toggle a flashlight on and off by pressing the "F" key. |
||||
- A sound should be played when toggling the flashlight on or off. |
||||
- when walking should produce the sound of footsteps on the floor. |
||||
- The sound of player footsteps should be different on at least 3 different surfaces: concrete, dirt and grass. |
||||
- Once the player collects the 8 pages, the forest turns from night to day for a while and then the game ends and the credits show up on the screen. |
||||
- The credits should mention the names of the developers. |
||||
|
||||
If you want you could try to play the real game [Slender: The Eight Pages](https://pt.wikipedia.org/wiki/Slender:_The_Eight_Pages) to get a feel of what your game should look like. |
||||
|
||||
> Do not forget to zip up the project compile and save everything for peer correction. |
@ -0,0 +1,55 @@
|
||||
### Functional |
||||
|
||||
###### When you open the game, is there a button to press to start playing? |
||||
|
||||
###### Is the map a large squared landscape terrain, scaled at 10 by 10 units? |
||||
|
||||
###### Is the action happening at night time in a forest-like environment? |
||||
|
||||
###### Does the map contain trees, little facilities (like shelters or little buildings), monuments, rocks and grass around the landscape? |
||||
|
||||
###### Were the buildings created using [BSP](https://www.worldofleveldesign.com/categories/ue4/bsp-01-what-is-bsp.php)? |
||||
|
||||
###### Does the map contain 8 pages spread around the map in the facilities or monuments the student created? |
||||
|
||||
###### Does the map contains at least three different types of floor surfaces: dirt, grass and concrete? |
||||
|
||||
###### If you exit and re-enter the game, did the pages changed spots on the locations? |
||||
|
||||
###### Does the monster come to standstill if it enters the field of view of the player? |
||||
|
||||
###### Does the "Creep" randomly teleports to another location? |
||||
|
||||
###### Does the "Creep" only appears after the player collects one page? |
||||
|
||||
###### Does the monster makes the task of collecting the 8 pages more difficult? |
||||
|
||||
###### Does a music/sound gets played and the camera starts to stutter when the creature appears in the sight of the player? |
||||
|
||||
###### Is the player controlling a FPS (First Person Shooter) character? |
||||
|
||||
###### Can the player move around using the WASD keys and look around using mouse input? |
||||
|
||||
###### Can the player collect the pages by left-clicking on them? |
||||
|
||||
###### Is a sound played when the player collects a page? |
||||
|
||||
###### Is a text displayed stating how many pages are left every time the player collects a page? |
||||
|
||||
###### Can the player toggle a flashlight on or off when pressing the "F" key? |
||||
|
||||
###### Is a sound played when toggling the flashlight on or off? |
||||
|
||||
###### Can you hear the sound of the player footsteps when he walks? |
||||
|
||||
###### Are there three different sounds to the footsteps, when on dirt, grass and concrete? |
||||
|
||||
###### Does the forest turns from night time to day time when the player collects all of the 8 pages? |
||||
|
||||
###### When finishing the game, do the credits (names of the developers) show up? |
||||
|
||||
### Bonus |
||||
|
||||
###### Does the game contain a 3D Main menu? |
||||
|
||||
###### Is the creature different from the one provided? |
Loading…
Reference in new issue