Browse Source

Merge branch 'dev' into tim

remotes/origin/tim
fdai7727 11 months ago
parent
commit
78e9036601
  1. 1
      .gitignore
  2. 317
      src/main/c/Jason/ASCII_art.c
  3. 30
      src/main/c/Jason/ASCII_art.h
  4. 0
      src/main/c/Stefan/place_your_code_here.txt
  5. 164
      src/main/c/Stefan/slot_machine.c
  6. 19
      src/main/c/Stefan/slot_machine.h
  7. 24
      src/main/c/main.c
  8. 107
      src/test/c/Jason/test_ASCII_art.c
  9. 0
      src/test/c/Stefan/place_your_tests_here.txt
  10. 224
      src/test/c/Stefan/test_slot_machine.c

1
.gitignore

@ -10,6 +10,7 @@ cmake-build-debug
past
CMakeLists.txt
toDo.md
.DS_Store
# Prerequisites
*.d

317
src/main/c/Jason/ASCII_art.c

@ -0,0 +1,317 @@
#include "ASCII_art.h"
#include <stdio.h>
int ASCII_Art(){
int weitermachen = 0;
do {
printWelcomeMessage();
int auswahl;
scanf("%d", &auswahl);
auswahlDerArt(auswahl);
printf("Vielen Dank, dass sie sich ASCII-Art angesehen haben\n"
"Wollen Sie weitere ASCII-Art sehen?\n"
"(1) Ja\n"
"(2) Nein\n"
"Eingabe:");
scanf("%d", &weitermachen);
}while(weitermachen == 1);
return 0;
}
void quadrat(){
frageNachGroesse();
int groesse;
scanf("%d", &groesse);
int arraySize = berechnungDerLaengeDesQuadratArrays(groesse);
char Quadrat[arraySize];
befuellenDesArraysMitX(Quadrat, arraySize);
befuelleArrayMitLeerzeichen(Quadrat, arraySize);
befuelleArrayMitZeilenumbruechen(Quadrat,groesse);
printf("\n%s", Quadrat);
}
void weihnachtsbaum(){
abfrageDerHoehe();
int hoehe;
do{
// Diese Schleifen erfragen user input solange bis korrekte Werte eingegeben werden
scanf("%d", &hoehe);
if (hoehe < 3){
printf("\nDer Weihnachtsbaum muss mindestens 3 Zeilen groß sein!\n");
printf("Bitte geben Sie erneut einen Wert ein der mindestens 3 lautet:");
}
}while(hoehe < 3);
int maxBreiteDesWeihnachtsbaums = max_breite(hoehe);
int mitte_baum = mitteDesBaums(maxBreiteDesWeihnachtsbaums);
int groesseDesArrays = (hoehe -1) * maxBreiteDesWeihnachtsbaums;
char weihnachtsbaum[groesseDesArrays];
befuellenDesWeihnachtsbaumsMitLeerzeichen(weihnachtsbaum, groesseDesArrays);
befuellenDesWeihnachtsbaumsMitPlus(weihnachtsbaum, maxBreiteDesWeihnachtsbaums, (hoehe-1));
befuellenDesWeihnachtsbaumsMitZeilenumbruechen(weihnachtsbaum, hoehe, maxBreiteDesWeihnachtsbaums);
char stamm[maxBreiteDesWeihnachtsbaums];
befuellenDesStammarraysMitLeerzeichen(stamm, maxBreiteDesWeihnachtsbaums);
stammAnRichtigerStelleEinsetzen(stamm, maxBreiteDesWeihnachtsbaums);
// Felder für Stamm und Baumspitze werden der Einfachheit halber getrennt befüllt und ausgegeben
printf("%s\n", weihnachtsbaum);
printf("%s", stamm);
}
void dreieck(){
dreieckWillkommensnachricht();
int hoehe;
do{
scanf("%d", &hoehe);
if(hoehe < 2){
printf("Es wurde ein Wert eingegeben, der kleiner ist als 2. Bitte geben Sie erneut eine Zahl ein!\n"
"Eingbe:");
}
} while(hoehe < 2);
int arraygroesse = berechnungDerDreieckArraygroesse(hoehe);
char dreieck[arraygroesse];
befuellenDesDreiecksMitX(dreieck, arraygroesse);
befuellenDesDreiecksMitZeilenumbruechen(dreieck, hoehe, arraygroesse);
printf("%s", dreieck);
}
void rakete(){
raketeBegruessung();
int hoehe;
do{
scanf("%d", &hoehe);
if(hoehe < 3){
printf("Es wurde ein Wert eingegeben, der kleiner ist als 3. Bitte geben Sie erneut eine Zahl ein!\n"
"Eingbe:");
}
} while(hoehe < 3);
}
int printWelcomeMessage(){
printf("Willkommen bei ASCII-Art!\n");
printf("Wählen Sie aus welche ASCII-Art Sie sehen wollen!\n");
printf("(1) Quadrat\n");
printf("(2) Weihnachtsbaum\n");
printf("(3) Dreieck\n");
printf("(4) Rakete\n");
return 0;
}
void auswahlDerArt(int pick){
switch (pick) {
case (1):
quadrat();
break;
case (2):
weihnachtsbaum();
break;
case (3):
dreieck();
break;
case (4):
rakete();
break;
default:
break;
}
}
int frageNachGroesse(){
printf("Sie haben ausgewählt, dass sie ein Quadrat sehen möchten!\n");
printf("Geben Sie ein wie lang die Seiten des Quadrats sein sollen:");
return 0;
}
int berechnungDerLaengeDesQuadratArrays(int anzahlDerX){
int ArraygroesseDesQuadrats;
ArraygroesseDesQuadrats = 2 * anzahlDerX * anzahlDerX;
// länge des Arrays für ein Quadrat
return ArraygroesseDesQuadrats;
}
void befuellenDesArraysMitX(char quadraT[], int laenge){
for (int i = 0; i < laenge; i++){
quadraT[i] = 'X';
}
quadraT[laenge-1] = '\0';
}
void befuelleArrayMitLeerzeichen(char quadraT[], int laenge){
for (int i = 0; i < laenge; i++){
if(i % 2 != 0){
quadraT[i] = ' ';
}
}
quadraT[laenge-1] = '\0';
}
void befuelleArrayMitZeilenumbruechen(char quadraT[], int laenge){
int zeile = 2 * laenge;
int laengeGesamt = zeile * laenge;
for (int i = 0; i < laengeGesamt; i++){
if((i + 1) % zeile == 0){
quadraT[i] = '\n';
}
}
quadraT[laengeGesamt-1] = '\0';
}
int abfrageDerHoehe(){
printf("Sie haben den Weihnachtsbaum ausgewählt!\n");
printf("Wählen Sie aus wie hoch der Weihnachtsbaum werden soll:");
return 0;
}
int max_breite(int zeilen){
int maximaleBreiteEinerZeile;
maximaleBreiteEinerZeile = zeilen + (zeilen - 2);
return maximaleBreiteEinerZeile;
}
int mitteDesBaums(int maxBreite){
int mitteVonBaum = maxBreite / 2;
return mitteVonBaum;
}
void befuellenDesWeihnachtsbaumsMitLeerzeichen(char arr[],int groesse){
for(int i = 0; i < groesse; i++){
arr[i] = ' ';
}
arr[groesse - 1] = '\0';
}
void befuellenDesWeihnachtsbaumsMitPlus(char arr[], int maxBreite, int zeilen){
int arrayGroesse = maxBreite * zeilen;
int mitteDesBaums = maxBreite / 2;
int mengeX = 1;
for(int i = zeilen; i > 0; i--){
int position = mitteDesBaums -1;
while(position < mitteDesBaums-1 + mengeX){
arr[position++] = '+';
}
mitteDesBaums += (maxBreite -1);
mengeX += 2;
}
arr[arrayGroesse] = '\0';
}
void befuellenDesWeihnachtsbaumsMitZeilenumbruechen(char arr[], int zeilen, int breite){
// man muss von der eingegebenen Höhe eins abziehen, weil der Stamm in diesem Array nicht inbegriffen ist
int arraygroesse = (zeilen-1) * breite;
// \n soll am Ende jeder Zeile platziert werden
for (int i = 0; i < arraygroesse; i++){
if((i + 1) % breite == 0 ){
arr[i] = '\n';
}
}
arr[arraygroesse -1] = '\0';
}
void befuellenDesStammarraysMitLeerzeichen(char arr[], int breite){
for(int i = 0; i < breite; i++){
arr[i] = ' ';
}
}
void stammAnRichtigerStelleEinsetzen(char arr[], int breite){
int stelleFuerStamm = breite / 2;
arr[stelleFuerStamm-1] = '+' ;
arr[breite - 1] = '\0';
}
void dreieckWillkommensnachricht(){
printf("Sie haben das Dreieck Ausgewählt!\n"
"Bitte geben Sie ein wie hoch das gewünschte Dreieck sein soll\n"
"(Es muss jedoch mindestens 2 hoch sein)\n"
"Eingabe:");
}
int berechnungDerDreieckArraygroesse(int zeilen){
int arraygroesseInklusiveEinerreiheOhneXOderBackslashN;
// Berechnung inklusive der \n
zeilen +=1;
// zum Aufsummieren der nötigen Feldgroesse bietet sich die Gaußsche Summenformel an
arraygroesseInklusiveEinerreiheOhneXOderBackslashN = zeilen * (zeilen+1) / 2;
// Das Array beginnt in der ersten Zeile mit 2 Elementen, also muss 1 subtrahiert werden nach Gauß
arraygroesseInklusiveEinerreiheOhneXOderBackslashN -= 1;
return arraygroesseInklusiveEinerreiheOhneXOderBackslashN;
}
void befuellenDesDreiecksMitX(char arr[], int goresse){
for(int i = 0; i < goresse; i++){
arr[i] = 'X';
}
arr[goresse-1] = '\0';
}
void befuellenDesDreiecksMitZeilenumbruechen(char arr[], int gesamtzeilen, int arraygroesse){
int stelleFuerZeilenumbruch = 1;
for(int zeile = 1; zeile <= gesamtzeilen; zeile++){
arr[stelleFuerZeilenumbruch] = '\n';
stelleFuerZeilenumbruch += (zeile+2);
}
arr[arraygroesse] = '\0';
}
void raketeBegruessung(){
printf("Sie haben die ASCII-Art Rakete ausgewählt ! Bitte Geben Sie ein wie hoch die Rakete sein soll\n"
"(Mindestens 3)\n"
"Eingabe:");
}

30
src/main/c/Jason/ASCII_art.h

@ -0,0 +1,30 @@
#ifndef ASCII_ART_H
#define ASCII_ART_H
int ASCII_Art();
int printWelcomeMessage();
void auswahlDerArt(int);
void quadrat();
int frageNachGroesse();
int berechnungDerLaengeDesQuadratArrays(int);
void befuellenDesArraysMitX(char[], int);
void befuelleArrayMitLeerzeichen(char[],int);
void befuelleArrayMitZeilenumbruechen(char[],int);
void weihnachtsbaum();
int abfrageDerHoehe();
int max_breite(int);
int mitteDesBaums(int);
void befuellenDesWeihnachtsbaumsMitLeerzeichen(char[],int);
void befuellenDesWeihnachtsbaumsMitPlus(char[], int, int);
void befuellenDesWeihnachtsbaumsMitZeilenumbruechen(char[], int, int);
void befuellenDesStammarraysMitLeerzeichen(char[], int);
void stammAnRichtigerStelleEinsetzen(char[], int);
void dreieck();
void dreieckWillkommensnachricht();
int berechnungDerDreieckArraygroesse(int);
void befuellenDesDreiecksMitX(char[], int);
void befuellenDesDreiecksMitZeilenumbruechen(char[], int, int);
void rakete();
void raketeBegruessung();
#endif

0
src/main/c/Stefan/place_your_code_here.txt

164
src/main/c/Stefan/slot_machine.c

@ -0,0 +1,164 @@
#include "slot_machine.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
void slotMachine(){
welcomeMessage();
char symbols[NUM_OF_SYMBOLS];
int balance = getBalance();
while(balance > 0){
int bet = getBet(balance);
balance = subtractBetFromBalance(bet, balance);
randomizeSymbols(symbols);
balance = spin(symbols, bet, balance);
}
}
int getBalance(){
int balance;
printf("Guthaben einwerfen: ");
balance = userInput();
printf("Dein Guthaben: %d\n", balance);
return balance;
}
int userInput(){
int input;
scanf("%d", &input);
return input;
}
int getBet(int balance){
while(1){
printf("Wetteinsatz: ");
int bet = userInput();
if(bet <= balance && bet > 0){
return bet;
} else {
printf("Ungueltige Eingabe!\n");
}
}
}
int subtractBetFromBalance(int bet, int balance){
return balance - bet;
}
void randomizeSymbols(char symbols[]){
srand(time(NULL));
for (int i = 0; i < NUM_OF_SYMBOLS; i++) {
int r = rand() % 100;
// 35% chance für A
if (r < 35) {
symbols[i] = 'A';
}
// 30% chance für B
else if (r < 65) {
symbols[i] = 'B';
}
// 20% chance für C
else if (r < 85) {
symbols[i] = 'C';
}
// 15% chance für D
else {
symbols[i] = 'D';
}
}
}
int spin(char symbols[], int bet, int balance){
int winnings = getWinnings(symbols, bet);
showResult(symbols, winnings);
balance += winnings;
printf("Aktuelles Guthaben: %d\n-------------------------\n", balance);
return balance;
}
int getWinnings(char symbols[], int bet){
int winnings = 0;
// 0 | 1 | 2
// 3 | 4 | 5
// 6 | 7 | 8
// 3 gleiche Symbole in einer Reihe gewinnen, Gewinn berechnen
for (int i = 0; i < ROWS; i++){
if (symbols[i * ROWS] == symbols[i * ROWS + 1] && symbols[i * ROWS] == symbols[i * ROWS + 2]) {
switch(symbols[i * ROWS]){
case 'A': winnings += bet * 3; break;
case 'B': winnings += bet * 5; break;
case 'C': winnings += bet * 10; break;
case 'D': winnings += bet * 20; break;
}
}
}
if (winnings > 0) {
printf("\nDu hast %d gewonnen!\n", winnings - bet);
}
else {
printf("\nLeider verloren.\n");
}
return winnings;
}
void showResult(char symbols[], int winnings){
char winnerMessage[] = {""};
if(winnings > 0){
strcpy(winnerMessage, " WINNER ");
} else {
strcpy(winnerMessage, " LOSER ");
}
printf("\n"
" .-------.\n"
" {-%s-} \n"
" .=============.\n"
" | | __\n"
" | [%c] [%c] [%c] |( )\n"
" | [%c] [%c] [%c] | ||\n"
" | [%c] [%c] [%c] | ||\n"
" | |_||\n"
" | xxx ::::::: |--'\n"
" | ooo ::::::: |\n"
" | $$$ ::::::: |\n"
" | __ |\n"
" |_____/__\\____|\n\n", winnerMessage, symbols[0], symbols[1], symbols[2], symbols[3], symbols[4], symbols[5], symbols[6], symbols[7], symbols[8]);
}
void welcomeMessage(){
printf("Herzlich Willkommen zur \n\n"
" _ _ _ _ \n"
" | | | | | | (_) \n"
" ___| | ___ | |_ _ __ ___ __ _ ___| |__ _ _ __ ___ \n"
"/ __| |/ _ \\| __| | '_ ` _ \\ / _` |/ __| '_ \\| | '_ \\ / _ \\\n"
"\\__ \\ | (_) | |_ | | | | | (_| | (__| | | | | | | | __/\n"
"|___/_|\\___/ \\__| |_| |_| |_|\\__,_|\\___|_| |_|_|_| |_|\\___|\n\n");
}

19
src/main/c/Stefan/slot_machine.h

@ -0,0 +1,19 @@
#ifndef SLOT_MACHINE_H
#define SLOT_MACHINE_H
#define NUM_OF_SYMBOLS 9
#define ROWS 3
void slotMachine();
void welcomeMessage();
int getBalance();
int userInput();
int getBet(int balance);
int subtractBetFromBalance(int bet, int balance);
void randomizeSymbols(char symbols[]);
int spin(char symbols[], int bet, int balance);
int getWinnings(char symbols[], int bet);
void showResult(char symbols[], int winnings);
#endif // SLOT_MACHINE_H

24
src/main/c/main.c

@ -14,6 +14,8 @@
#include "SchereSteinPapier.h"
#include "hangman.h"
#include "tictactoe.h"
#include "Jason/ASCII_art.h"
#include "Stefan/slot_machine.h"
void openInterface();
@ -35,9 +37,19 @@ void openInterface()
"Du hast folgende Spiele zur Auswahl:\n\n"
"1: Schere-Stein-Papier\n"
"2: Hangman\n"
"3: TicTacToe\n");
"3: TicTacToe\n"
"4: Slot Machine\n"
"5: ASCII - Art\n");
printf("\nBitte waehle die Zahl des entsprechenden Spiels aus, um damit zu starten.\nAm Ende eines Spiels kannst du mit der Taste 0 wieder zurueck zum Hauptmenue kommen.\nIm Hauptmenue beendest du mit der Auswahl 0 das Programm \n\n");
scanf_s("%d", &selection);
#ifdef __APPLE__
scanf("%d", &selection);
#elif defined(__linux__)
scanf("%d", &selection);
#else
scanf_s("%d", &selection);
#endif
//todo
@ -54,12 +66,12 @@ void openInterface()
case(3):
startTicTacToe();
break;
/*case(4):
//Spiel()
case(4):
slotMachine();
break;
case(5):
//Spiel()
break;*/
ASCII_Art();
break;
default:
break;
}

107
src/test/c/Jason/test_ASCII_art.c

@ -0,0 +1,107 @@
#include "unity.h"
#include "ASCII_art.h"
void setUp (void){
}
void tearDown(void){
}
void test_doesWelcomeMessageWork() {
//arrange
int expectedResult = 0;
//act
int actualResult = printWelcomeMessage();
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_funktioniertDieAbfrageDerGroesse() {
//arrange
int expectedResult = 0;
//act
int actualResult = frageNachGroesse();
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_korrekteBerechnungDerArrayGroesse() {
//arrange
int expectedResult = 200;
//act
int actualResult = berechnungDerLaengeDesQuadratArrays(10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_stringAbgleich(void){
// arrange
char expectedMessage[] = "XXXXXXX";
// act
char message[9];
befuellenDesArraysMitX(message, 8);
// assert
TEST_ASSERT_EQUAL_STRING(expectedMessage, message);
}
void test_stringAbgleichMitLeerzeichen(void){
// arrange
char expectedMessage[] = "X X X X X X X X X";
// act
char message[19];
befuellenDesArraysMitX(message, 18);
befuelleArrayMitLeerzeichen(message, 18);
// assert
TEST_ASSERT_EQUAL_STRING(expectedMessage, message);
}
void test_stringAbgleichMitLeerzeichenUndZeilenumbruch(void){
// arrange
char expectedMessage[] = "X X X\nX X X\nX X X";
// act
char message[19];
befuellenDesArraysMitX(message, 18);
befuelleArrayMitLeerzeichen(message, 18);
befuelleArrayMitZeilenumbruechen(message, 3);
// assert
TEST_ASSERT_EQUAL_STRING(expectedMessage, message);
}
void test_erscheintDieAbfrageFuerWeihnachtsbaum() {
//arrange
int expectedResult = 0;
//act
int actualResult = abfrageDerHoehe();
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_korrekteBerechnungAufMaximaleBreiteWeihnachtsbaum() {
//arrange
int expectedResult = 10;
//act
int actualResult = max_breite(6);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}

0
src/test/c/Stefan/place_your_tests_here.txt

224
src/test/c/Stefan/test_slot_machine.c

@ -0,0 +1,224 @@
#include "slot_machine.h"
#include "unity.h"
void setUp() {}
void tearDown() {}
void test_subtract_bet_10_from_balance_10() {
//arrange
int expectedResult = 0;
//act
int actualResult = subtractBetFromBalance(10, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_subtract_bet_0_from_balance_10() {
//arrange
int expectedResult = 10;
//act
int actualResult = subtractBetFromBalance(0, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_subtract_bet_5_from_balance_10() {
//arrange
int expectedResult = 5;
//act
int actualResult = subtractBetFromBalance(5, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_no_rows_won_bet_equals_10() {
//arrange
char testSymbols[] = {"AABAACAAD"};
int expectedResult = 0;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_A_won_bet_equals_10() {
//arrange
char testSymbols[] = {"AAAAACAAD"};
int expectedResult = 30;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_B_won_bet_equals_10() {
//arrange
char testSymbols[] = {"BBBAACAAD"};
int expectedResult = 50;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_C_won_bet_equals_10() {
//arrange
char testSymbols[] = {"BABAACCCC"};
int expectedResult = 100;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_D_won_bet_equals_10() {
//arrange
char testSymbols[] = {"BABDDDCAC"};
int expectedResult = 200;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_6_A_won_bet_equals_10() {
//arrange
char testSymbols[] = {"AAAAAACAC"};
int expectedResult = 60;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_6_B_won_bet_equals_10() {
//arrange
char testSymbols[] = {"BBBBBBCAC"};
int expectedResult = 100;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_6_C_won_bet_equals_10() {
//arrange
char testSymbols[] = {"CCCCCCCAC"};
int expectedResult = 200;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_6_D_won_bet_equals_10() {
//arrange
char testSymbols[] = {"DDDDDDCAC"};
int expectedResult = 400;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_A_3_B_won_bet_equals_10() {
//arrange
char testSymbols[] = {"AAABBBCAC"};
int expectedResult = 80;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_C_3_D_won_bet_equals_10() {
//arrange
char testSymbols[] = {"BAACCCDDD"};
int expectedResult = 300;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_9_A_won_bet_equals_10() {
//arrange
char testSymbols[] = {"AAAAAAAAA"};
int expectedResult = 90;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
void test_3_B_3_C_3_D_won_bet_equals_10() {
//arrange
char testSymbols[] = {"BBBCCCDDD"};
int expectedResult = 350;
//act
int actualResult = getWinnings(testSymbols, 10);
//assert
TEST_ASSERT_EQUAL_INT(expectedResult, actualResult);
}
Loading…
Cancel
Save