Trädvy Permalänk
Medlem
Registrerad
Feb 2016

Hjälp med fem i rad c++

Hejsan mitt namn är Josefine!
Jag går programmering 1 på gymnasiet och har en uppgift att göra ett spel. Jag valde fem i rad då jag inte hittade något enklare, läraren sa att jag ska kunna ha en pekare som gör så att om jag ex trycker på space så läggs x eller o där jag vill lägga den på planen, jag måste även göra så att jag kan spela mot datorn tror jag, ingen aning om hur jag ska börja, försökt googla men hittar bara svåra koder jag inte förstår, någon som har gjort detta spel och kan dela med sig så att jag kan få inspireras och kunna skriva om koden så jag förstår! Tacksam för all hjälp!

Trädvy Permalänk
Medlem
Registrerad
Mar 2015

Låter svårt om du inte fått lektioner som gör att du kommer igång. Svårt att förstå var det blir svårt för dig. Har du en miljö (kompilator+editor) för c++ som gör det enkelt att komma igång med ett sk Hello World program? Att spela mot datorn kan inte ses som en lämplig uppgift att börja med, att ens hantera muspekare och grafik kan vara svårt nog om man inte har ett ramverk som hjälper till med dessa delar. Hur koden ser ut (delar som hanterar grafiken) beror på vilket operativsystem det körs på.

Trädvy Permalänk
Medlem
Registrerad
Feb 2016

@Mordekai: Har Visual studio 2015 och windows 8, jag är så svårlärd, glömmer typ allt så minns inte hur jag ska göra riktigt :/

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jan 2005

Ett tips är ju att inte arbeta med grafik till en början... Låt programmet skriva ut rader som representerar spelplanen, t.ex.

- - - - - - - A - - - B A - - B B A - A

Där - är tomma platser, A och B är spelare. Väl var man vill lägga sin bricka med t.ex. A1 där A är kolumnen och 1 raden. Skriv sedan ut "spelplanen" på nytt efter varje omgång.

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2008

Hej skrev ett litet exempel på ett 5 i rad.
Mer C än C++ men det borde hjälpa dig att förstå hur du kan göra ett enkelt 5 i rad.

Om man sammanfattar programmet.
Du behöver något att representera spelplanen, i detta fall t.ex. ett 2-Diemensionellt fält av karaktärer.
Du behöver kunna placera en pjäs, av två olika typer. X, O.
Du behöver kontrollera om en spelare vinner.
Du behöver en spelloop som ritar ut spelplanen på skärmen, samt tar hand om inmatningar från spelare.

I detta exemplet väljer datorspelaren sitt drag slumpvis, om du vill ha bättre motståndare får man tänka ut en strategi eller implementera någon befintlig algoritm, men jag tror det är utanför ramen för din uppgift.

Hoppas det är till någon hjälp.

// ------------------ // | Fem-I-Rad Spel | // ------------------ // Inkludera filer som används. #include <stdio.h> // printf, scanf_s (utmatning, inmatning) #include <stdlib.h> // srand, rand (slumpgenerator) #include <time.h> // time (klockan) // Vi börjar med att definiera konstanter för spelet. #define BOARD_SIZE 10 // Storleken på spelplanen. #define MARKERS_TO_WIN 5 // Antal pjäser i rad som krävs för att vinna. #define EMPTY_MARKER '-' // Bokstav som representerar en tom ruta på spelplanen. #define PLAYER_1_MARKER 'X' // Boksatav som representerar den första spelarens pjäser. #define PLAYER_2_MARKER 'O' // Boksatav som representerar den andra spelarens pjäser. // Deklarera Globala variabler som spelet använder. char board[BOARD_SIZE][BOARD_SIZE]; // 2-Dimensionell array av bokstäver som representerar spelplanen, bokstäverna kan antingen vara "EMPTY_MARKER", "PLAYER_1_MARKER" eller "PLAYER_2_MARKER". int lastMarkerX, lastMarkerY; // Vi lagrar positionen för den senaste placerade spelpjäsen, därför att vi kan då enkalre testa om en spelare har vunnit. // Funktioner som spelet använder sig utav. void initBoard(); // Nollställa spelplanen. void printBoard(); // Skriva ut spelplanen. bool placeMarker(int x, int y, char marker); // Placera spelpjäs. void playMultiplayer(); // Själva spelet för två spelare. void playSingleplayer(); // Själva spelet mot dator. bool humanTurn(char marker); // En mänsklig spelares drag. bool computerTurn(char marker); // Datorns drag. bool checkWin(); // Kolla om senaste draget gjorde att spelaren vann. bool checkMultiplayer(); // Kolla om användaren vill spela mot en annan spelare, eller mot datorn. // Huvudprogrammet, detta körs när programet startas. int main(){ printf("Welcome to 5-in-a-row!\n"); // Skriv ut välkomst text. srand(time(NULL)); // Initiera slumpgenerator från klockan. initBoard(); // Nollställer spelplanen. if (checkMultiplayer()) // Kolla om det ska vara multiplayer. playMultiplayer(); // Starta spelet för två spelare. else playSingleplayer(); // Annars starta spelet för en spelare. return 0; } // Kolla om användaren vill spela mot en annan spelare, eller mot datorn. bool checkMultiplayer() { char choice; // Bokstav för val som användaren anger. printf("Select gamemode:\n"); // Skriv ut val av spelläge. printf("1.) Human vs human.\n"); // Skriv ut Alternativ 1, två spelare mot varandra. printf("2.) Human vs computer.\n"); // Skriv ut Alternativ 2, spelare mot dator. printf("Your choice: "); // Skriv ut ange val. scanf_s("%c", &choice); // Låt användare skriva in sitt val. if (choice == '1') return true; // Om Alternativ 1, returnera sant return false; // Annars, returnara falskt. } // Själva spelet för två spelare. void playMultiplayer() { printBoard(); char currentPlayer = PLAYER_1_MARKER; // Variabel för den nuvarande spelaren som har sin tur att spela. bool done = false; // Variabel för att se om spelet är klart eller som det ska fortsätta. while (!done) { // När spelet inte är klart, fortsätt spela. printf("Player %c:s turn\n", currentPlayer); // Skriv ut vems tur att spela. while (!humanTurn(currentPlayer)); // Vi använder en loop, så om spelaren misslyckas med att välja en ruta får denne försöka igen. printBoard(); // Rita ut spelplanen. done = checkWin(); // Kolla om spelaren vann. currentPlayer = currentPlayer == PLAYER_1_MARKER ? PLAYER_2_MARKER : PLAYER_1_MARKER; // Här byter vi till nästa spelare. } printf("Congratualtions Player %c, you won!\n", board[lastMarkerX][lastMarkerY]); // Skriv ut vem som vann. } // En människas tur att spela. bool humanTurn(char marker) { int x, y; // Variabler Rad och kolumn som spelaren vill placera sin pjäs på. printf("Select location to place marker...\n"); // Skriver ut att spelaren ska välja var hon vill placera sin pjäs. printf("Enter row: "); // Skriver ut frågan om vilken rad spelaren vill placera på. scanf_s("%d", &x); // Låter spelaren skriva in vilken rad som den vill placera spelpjäsen på. printf("Enter column: "); // Skriver ut frågan om vilken kolumn spelaren vill placera på. scanf_s("%d", &y); // Låter spelaren skriva in vilken kolumn som den vill placera spelpjäsen på. return placeMarker(x, y, marker); // Placera pjäsen på spelplanen. } // Placera spelpjäs. bool placeMarker(int x, int y, char marker) { if (board[x][y] != EMPTY_MARKER) return false; // Om det redan finns än pjäs på rutan, returnera falskt. (det gick ej att placera pjäsen). board[x][y] = marker; // Placera spelpjäsen på brädet. lastMarkerX = x; // Vi lägger undan raden för pjäsen i den globala variabeln för senast placerade pjäs rad position. lastMarkerY = y; // Vi lägger undan kolumnen för pjäsen i den globala variabeln för senast placerade pjäs kolumn position. return true; } // Skriva ut spelplanen. void printBoard() { printf(" "); // Skriv ut tomma mellanslag för att snygga till. for (int i = 0; i < BOARD_SIZE; i++) printf("%2d", i); // Skriv ut nummer för kolumnerna. for (int i = 0; i < BOARD_SIZE; i++) { // Gå igenom alla rader. printf("\n%2d ", i); // för varje rad på spelplanen, skriv ut en ny rad, och skriv ut nummer för raderna. for (int j = 0; j < BOARD_SIZE; j++) // Gå igenom alla kolumner. printf("%c ", board[i][j]); // Skriv ut spelmarkörerna på spelplannen. } printf("\n"); // Byt rad. } // Nollställa spelplanen. void initBoard() { for (int i = 0; i < BOARD_SIZE; i++) // Gå igenom alla rader. for (int j = 0; j < BOARD_SIZE; j++) // Gå igenom alla kolumner. board[i][j] = EMPTY_MARKER; // Placera en tom markör på spelplanen. } // Kollar om den senaste placerade pjäsen gjorde att spelaren vann. bool checkWin() { char marker = board[lastMarkerX][lastMarkerY]; // Senaste spelarens spelpjäs. int left = 0, right = 0, up = 0, down = 0; // Antal likadana pjäser längs olika riktningar. int leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0; // Undersök vinst: vertikalt. for (int x = lastMarkerX; x >= 0; x--) { // Kolla alla pjäser upp. if (board[x][lastMarkerY] == marker) up++; // Om samma pjäs: öka antal pjäser i rad upp med ett. else break; // Om inte samma pjäs: sluta kolla åt upp. } for (int x = lastMarkerX; x < BOARD_SIZE; x++) { // Kolla alla pjäser ned. if (board[x][lastMarkerY] == marker) down++; // Om samma pjäs: öka antal pjäser i rad ned med ett. else break; // Om inte samma pjäs: sluta kolla åt ned. } if (up + down > MARKERS_TO_WIN) return true; // Om antal pjäser till upp och ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: horisontellt. for (int y = lastMarkerY; y >= 0; y--) { // Kolla alla pjäser vänster. if (board[lastMarkerX][y] == marker) left++; // Om samma pjäs: öka antal pjäser i rad vänster med ett. else break; // Om inte samma pjäs: sluta kolla åt vänster. } for (int y = lastMarkerY; y < BOARD_SIZE; y++) { // Kolla alla pjäser höger. if (board[lastMarkerX][y] == marker) right++; // Om samma pjäs: öka antal pjäser i rad höger med ett. else break; // Om inte samma pjäs: sluta kolla åt höger. } if (left + right > MARKERS_TO_WIN) return true; // Om antal pjäser till höger och vänster är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: diagonalt vänster-upp till höger-ned. for (int x = lastMarkerX, y = lastMarkerY; x >= 0 && y >= 0; x--, y--) { // Kolla alla pjäser vänster-upp. if (board[x][y] == marker) leftUp++; // Om samma pjäs: öka antal pjäser i diagonalen vänster-upp med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen vänster-upp. } for (int x = lastMarkerX, y = lastMarkerY; x < BOARD_SIZE && y < BOARD_SIZE; x++, y++) { // Kolla alla pjäser höger-ned. if (board[x][y] == marker) rightDown++; // Om samma pjäs: öka antal pjäser i diagonalen höger-ned med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen höger-ned. } if (leftUp + rightDown > MARKERS_TO_WIN) return true; // Om antal pjäser diagonalt vänster-upp till höger-ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: diagonalt höger-upp till vänster-ned. for (int x = lastMarkerX, y = lastMarkerY; x >= 0 && y < BOARD_SIZE; x--, y++) { // Kolla alla pjäser höger-upp. if (board[x][y] == marker) rightUp++; // Om samma pjäs: öka antal pjäser i diagonalen höger-upp med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen höger-upp. } for (int x = lastMarkerX, y = lastMarkerY; x < BOARD_SIZE && y >= 0; x++, y--) { // Kolla alla pjäser vänster-ned. if (board[x][y] == marker) leftDown++; // Om samma pjäs: öka antal pjäser i diagonalen vänster-ned med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen vänster-ned. } if (rightUp + leftDown > MARKERS_TO_WIN) return true; // Om antal pjäser diagonalt höger-upp till vänster-ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. return false; // Ingen vinst har hittats, alltså returnerar vi falskt. } // En dators tur att spela. bool computerTurn(char marker) { int x, y; // Variabler Rad och kolumn som datorn vill placera sin pjäs på. x = rand() % BOARD_SIZE; // Datorn väljer en slupvis rad på spelplanen. y = rand() % BOARD_SIZE; // Datorn väljer en slupvis kolumn på spelplanen. return placeMarker(x, y, marker); // Placerar pjäsen på spelplanen. } // Själva spelet mot dator. void playSingleplayer() { printBoard(); char currentPlayer = PLAYER_1_MARKER; // Variabel för den nuvarande spelaren som har sin tur att spela. bool done = false; // Variabel för att se om spelet är klart eller som det ska fortsätta. while (!done) { // När spelet inte är klart, fortsätt spela. printf("Player %c:s turn\n", currentPlayer); // Skriv ut vems tur att spela. if (currentPlayer == PLAYER_1_MARKER) // Kolla om människas tur. while (!humanTurn(currentPlayer)); // Vi använder en loop, så om spelaren misslyckas med att välja en ruta får denne försöka igen. else // Annars är det datorns tur. while (!computerTurn(currentPlayer)); printBoard(); // Rita ut spelplanen. done = checkWin(); // Kolla om spelaren vann. currentPlayer = currentPlayer == PLAYER_1_MARKER ? PLAYER_2_MARKER : PLAYER_1_MARKER; // Här byter vi till nästa spelare. } if (board[lastMarkerX][lastMarkerY] == PLAYER_1_MARKER) // Kolla om spelaren vann. printf("Congratualtions, you won!\n"); // Skriv ut vinst-text. else // Annars vann datorn. printf("To bad, you loose!\n"); // Skriv ut förlust-text. }

Trädvy Permalänk
Medlem
Plats
Karlstad
Registrerad
Jun 2011

@gustavwth: Gjorde du det där nu?
Din hjärna måste väga tretton kilo.

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

Hmm,

@Gustavwth må mena väl, men steget från "har ingen aning" till det lösningsutkastet är ganska långt.

Jag föreslår att du tar ett spel som Sten, Sax och Påse. Du behöver bara slumpa fram vilket alternativ programmet väljer och ha lite kontrollogik för att jämföra med användarens och se vem som vann.

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Hur kan detta vara en vettig uppgift i Programmering 1? Detta är inte speciellt lätt och ännu värre att du ska koda hur datorn ska spela.

Som personen över skrev, sten sax påse känns som ett mycket bättre val.

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2008

Om du vill utöka spelet så det går att använda muspekare, krävs lite annat tänk än ett vanligt sekventiellt program.

Om du vill använda musen och tangentbord måste man hantera händelser, då får man skriva ett spel på ett litet annat sätt.
Förslagsvis har man en tillståndsmaskin där spelet kan vara i flera olika lägen. Exempelvis ett tillstånd för meny, en för spelarens tur och en för datorns tur.

För att hantera mus & tangentbords-tryck har man en händelsehanterare, som ser till att det som ska utföras när en händelse inträffar sker.

Här är exemplet utökat för att klara av att hantera knapptryck med musen för att placera spelpjäserna.

Det är också bra att försöka separera spellogiken från grafiken, och händelsesystemet så mycket som möjligt. Ett designmönster som kallas MVC.

Nu är detta exempel skrivet i en enda fil med kommentarer för att det ska vara enkelt att överblicka och förstå.

Jag rekommenderar att du skriver ett mindre spel, men jag tror det är lärorikt att förstå hur det kan fungera.

Sedan om du vill har ett spel med finare grafik, ljud m.m, skulle jag rekommendera att du provar SDL.

// ---------------------------- // | Fem-I-Rad Spel Med Musen | // ---------------------------- #include <windows.h> // Händelser. #include <stdio.h> // Inmatning. #include <stdlib.h> // Slumpgenerator. #include <time.h> // Klockan.(används bara av slumpgeneratorn) // ------------------------------------------------------------------------------------------------------ // ---------------------- HÄNDELSE-KOD FÖRBEREDELSER ---------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // Definierar konstanter till fönster och händelser. #define MOUSE_PRESSED_OR_RELEASED 0 // 0 betyder att knapp är tryckt eller släppt. #define EVENT_BUFFER_SIZE 128 // Antal händelser som kan lagras i bufferten för händelser. // Globala variabler till fönster och händelser. INPUT_RECORD eventInputBuffer[EVENT_BUFFER_SIZE]; // Händelse Buffert DWORD nrOfEvents; // Antal händelser som ligger i händelse bufferten. HANDLE consoleInputHandle = GetStdHandle(STD_INPUT_HANDLE); // Hämtar hantaget till standard input som hör till konsollen. HANDLE consoleOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);// Hämtar hantaget till standard output som hör till konsollen. // Funktioner för händelsehantering. void initConsole(); // Ställer in konsollen för att hantera händelser. void clearScreen(); // Rensar skärmen och ställer in konsollen för att hantera händelser på nytt. void eventHandler(); // Läser in och hanterar händelser. void keyboardEventHandler(KEY_EVENT_RECORD); // Hanterar tangentbords-tryckningar. void mouseEventHandler(MOUSE_EVENT_RECORD); // Hanterar mus-tryckningar. // ------------------------------------------------------------------------------------------------------ // ---------------------- SPEL-KOD FÖRBEREDELSER -------------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // Vi börjar med att definiera konstanter för spelet. #define BOARD_SIZE 10 // Storleken på spelplanen. #define MARKERS_TO_WIN 5 // Antal pjäser i rad som krävs för att vinna. #define EMPTY_MARKER '-' // Bokstav som representerar en tom ruta på spelplanen. #define PLAYER_1_MARKER 'X' // Boksatav som representerar den första spelarens pjäser. #define PLAYER_2_MARKER 'O' // Boksatav som representerar den andra spelarens pjäser. // Vi definierar de olika lägen spellet kan befinna sig i. #define GAME_STATE_START_MENU 1 // Spelet kan vara i huvudmeny. #define GAME_STATE_HUMAN 2 // Det kan vara en människas tur att spela. #define GAME_STATE_COMPUTER 3 // Det kan vara en dators tur att spela. #define GAME_STATE_END 4 // Spelet är över. #define START_MENU_OPTION_MULTIPLAYER 1 // Vilken rad på menyn knappen för multiplayer ligger på. #define START_MENU_OPTION_SINGLEPLAYER 2 // Vilken rad på menyn knappen för singleplayer ligger på. // Deklarera Globala variabler som spelet använder. char currentGameState = GAME_STATE_START_MENU; // Variabel för nuvarande spelläge, spelet börjar på start menyn. char board[BOARD_SIZE][BOARD_SIZE]; // 2-Dimensionell array av bokstäver som representerar spelplanen, bokstäverna kan antingen vara "EMPTY_MARKER", "PLAYER_1_MARKER" eller "PLAYER_2_MARKER". int lastMarkerX, lastMarkerY; // Vi lagrar positionen för den senaste placerade spelpjäsen, därför att vi kan då enkalre testa om en spelare har vunnit. bool isMultiplayer; // Variabel som bestämmer om spelet är mot andra spelare eller mot datorn. char currentPlayer = PLAYER_1_MARKER; // Håller reda på vems tur det är, börjar på spelare ett. // Funktioner som spelet använder sig utav. void initBoard(); // Nollställa spelplanen. bool placeMarker(int x, int y, char marker); // Placera spelpjäs. void humanPlay(int x, int y); // Människans drag. bool computerPlay(char marker); // Datorns drag. bool checkWin(); // Kolla om senaste draget gjorde att spelaren vann. void gameRound(bool *done); // En runda på spelet. void startMenu(int y); // Startmeny. // Grafik funktioner. void printMenu(); // Skriv ut startmeny. void printBoard(); // Skriva ut spelplanen. void printVictory(); // Skriv ut vem som vann. // ------------------------------------------------------------------------------------------------------ // ---------------------- Huvudfunktionen som körs när programmet startas. ------------------------------ // ------------------------------------------------------------------------------------------------------ int main(){ initConsole(); // Ställer in konsollen för att hantera händelser. printMenu(); // Kolla om vi ska köra mot människa eller dator. printBoard(); // Ritar ut spelplanen. bool done = false; // Variabel som avgör om programmet ska avslutas. while (!done) { // Själva programloopen körs tills done är sant. eventHandler(); // Hanterar händelser som uppstår från användaren. gameRound(&done); // Kör En runda på spelet. } printVictory(); // Skriv ut vem som vann. system("pause"); // Pausa så att inte konsollen försvinner direkt. return 0; } // ------------------------------------------------------------------------------------------------------ // ---------------------- HÄNDELSE-KOD ------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------ // Läser in händelser som uppstår och vidarebefodrar dem till korrekt händelsehanterare. void eventHandler() { ReadConsoleInput(consoleInputHandle, eventInputBuffer, EVENT_BUFFER_SIZE, &nrOfEvents); // Hämtar händelser till bufferten: eventInputBuffer, och räknar antalet händelser till: nrOfEvents. for (int i = 0; i < nrOfEvents; i++) { // För varje händelse. switch (eventInputBuffer[i].EventType) { // Kolla vilken typ av händelse. case KEY_EVENT: // Om det är tangentbordstrckningar. keyboardEventHandler(eventInputBuffer[i].Event.KeyEvent); // Låt tangentbordshanteraren hantera händelsen. break; case MOUSE_EVENT: // Om det är tangentbordstrckningar. mouseEventHandler(eventInputBuffer[i].Event.MouseEvent); // Låt mushanteraren hantera händelsen. break; } } } // Tangentbordshändelsehanteraren hanterar knapptrckningar på tangentbordet. void keyboardEventHandler(KEY_EVENT_RECORD keyEvent) { if (!keyEvent.bKeyDown) { // Om vi släpper en tangent på skrivbordet. // Nu har vi inget som händer här, men här kan man lägga till flera händelser för att bygga vidare om man vill använda tangentbordet. } } // Mushändelsehanteraren hanterar knapptrckningar på musen. void mouseEventHandler(MOUSE_EVENT_RECORD mouseEvent) { if (mouseEvent.dwEventFlags == MOUSE_PRESSED_OR_RELEASED) { // Om musknappen trcks eller släpps. if (mouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) { // Om det är vänstra musknappen. const int mousePosX = mouseEvent.dwMousePosition.X; // Hämta muspekarens X position i konsollen. const int mousePosY = mouseEvent.dwMousePosition.Y; // Hämta muspekarens Y position i konsollen. int col, row; switch (currentGameState) { // Kolla spelläge. case GAME_STATE_HUMAN: // Om det är spelarens tur. col = mousePosX / 2; // Vi måste räkna med att vi ritar ut spelplanen med mellanrum. row = mousePosY; // Inget mellanrum mellan rader. humanPlay(row, col); // Spela pjäsen på den tryckta positionen. break; case GAME_STATE_START_MENU: // Om vi är i startmenyn. startMenu(mousePosY); // Testa startmenyn. break; } } } } // Initiera konsollen genom att tillåta händelser och ta bort markören. void initConsole() { SetConsoleMode(consoleInputHandle, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); // Vi aktiverar händelser till konsol-fönstret. CONSOLE_CURSOR_INFO cursor; cursor.bVisible = false; cursor.dwSize = 1, // Skapa en ny onsynlig markör. SetConsoleCursorInfo(consoleOutputHandle, &cursor); // Aktivera den onsynliga markören till konsolen, så vi inte ser en blinkande markör. } // ------------------------------------------------------------------------------------------------------ // ---------------------- GRAFIK-KOD -------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // Skriva ut spelplanen. void printBoard() { for (int i = 0; i < BOARD_SIZE; i++) { // Gå igenom alla rader. for (int j = 0; j < BOARD_SIZE; j++) // Gå igenom alla kolumner. printf("%c ", board[i][j]); // Skriv ut spelmarkörerna på spelplannen. printf("\n"); // Byt rad. } } // Kolla om användaren vill spela mot en annan spelare, eller mot datorn. void printMenu() { printf("Select gamemode with left mouse button.\n");// Skriv ut val av spelläge. printf("Human vs human.\n"); // Skriv ut Alternativ 1, två spelare mot varandra. printf("Human vs computer.\n"); // Skriv ut Alternativ 2, spelare mot dator. } // Skriv ut vem som vann. void printVictory() { printf("Congratualtions Player %c, you won!\n", board[lastMarkerX][lastMarkerY]); } // Rensar skärmen void clearScreen() { system("cls"); // Rensar skärmen. initConsole(); // Konsollen måste tillåta händelser. } // ------------------------------------------------------------------------------------------------------ // ---------------------- SPEL-KOD ---------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // En runda av spelet. void gameRound(bool *done) { switch (currentGameState) { // Kolla vilket spelläge spelet är i. case GAME_STATE_HUMAN: // Människans spel hanteras separat av händelser. break; case GAME_STATE_COMPUTER: // Om det är datorns tur att spela. while (!computerPlay(currentPlayer)); // Låt datorn göra sitt drag. clearScreen(); // Rensa skärmen. printBoard(); // Rita ut spelplanen. currentPlayer = currentPlayer == PLAYER_1_MARKER ? PLAYER_2_MARKER : PLAYER_1_MARKER; // Här byter vi till nästa spelare. currentGameState = GAME_STATE_HUMAN; // låt människan spela. if (checkWin()) currentGameState = GAME_STATE_END; // Kolla om vinst. break; case GAME_STATE_END: // Om spelet är slut. *done = true; // Avsluta spelet. break; } } // Om människa försöker spela. void humanPlay(int x, int y) { if (currentGameState == GAME_STATE_HUMAN) { if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE) { // Försök endast placera om vi är innanför banan. if (placeMarker(x, y, currentPlayer)) { // Om placering lyckades. clearScreen(); // Rensa skärmen. printBoard(); // Rita ut spelplanen. currentPlayer = currentPlayer == PLAYER_1_MARKER ? PLAYER_2_MARKER : PLAYER_1_MARKER; // Här byter vi till nästa spelare. if (!isMultiplayer) currentGameState = GAME_STATE_COMPUTER; // Om det är singleplayer, låt datorn spela. if (checkWin()) currentGameState = GAME_STATE_END; // Kolla om vinst. } } } } // En dators tur att spela. Här kan man vidareutveckla en strategi åt datorn, nu kör den slumpvis. bool computerPlay(char marker) { int x, y; // Variabler Rad och kolumn som datorn vill placera sin pjäs på. x = rand() % BOARD_SIZE; // Datorn väljer en slupvis rad på spelplanen. y = rand() % BOARD_SIZE; // Datorn väljer en slupvis kolumn på spelplanen. return placeMarker(x, y, marker); // Placerar pjäsen på spelplanen. } // Placera spelpjäs. bool placeMarker(int x, int y, char marker) { if (board[x][y] != EMPTY_MARKER) return false; // Om det redan finns än pjäs på rutan, returnera falskt. (det gick ej att placera pjäsen). board[x][y] = marker; // Placera spelpjäsen på brädet. lastMarkerX = x; // Vi lägger undan raden för pjäsen i den globala variabeln för senast placerade pjäs rad position. lastMarkerY = y; // Vi lägger undan kolumnen för pjäsen i den globala variabeln för senast placerade pjäs kolumn position. return true; } // Nollställa spelplanen. void initBoard() { for (int i = 0; i < BOARD_SIZE; i++) // Gå igenom alla rader. for (int j = 0; j < BOARD_SIZE; j++) // Gå igenom alla kolumner. board[i][j] = EMPTY_MARKER; // Placera en tom markör på spelplanen. } // Testa att klicka på en rad i startmenyn. void startMenu(int y) { switch (y) { // Kolla rad som klickades på. case START_MENU_OPTION_MULTIPLAYER: // Om multiplayer är valt. currentGameState = GAME_STATE_HUMAN;// Gå över till spelläget. isMultiplayer = true; // Välj multiplayer. initBoard(); // Nollställa spelplanen. clearScreen(); // Rensa skärmen printBoard(); // Rita ut spelplanen. break; case START_MENU_OPTION_SINGLEPLAYER: // Om singleplayer är valt. currentGameState = GAME_STATE_HUMAN;// Gå över till spelläget isMultiplayer = false; // Välj singleplayer. initBoard(); // Nollställa spelplanen. clearScreen(); // Rensa skärmen printBoard(); // Rita ut spelplanen. break; } } // Kollar om den senaste placerade pjäsen gjorde att spelaren vann. bool checkWin() { char marker = board[lastMarkerX][lastMarkerY]; // Senaste spelarens spelpjäs. int left = 0, right = 0, up = 0, down = 0; // Antal likadana pjäser längs olika riktningar. int leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0; // Undersök vinst: vertikalt. for (int x = lastMarkerX; x >= 0; x--) { // Kolla alla pjäser upp. if (board[x][lastMarkerY] == marker) up++; // Om samma pjäs: öka antal pjäser i rad upp med ett. else break; // Om inte samma pjäs: sluta kolla åt upp. } for (int x = lastMarkerX; x < BOARD_SIZE; x++) { // Kolla alla pjäser ned. if (board[x][lastMarkerY] == marker) down++; // Om samma pjäs: öka antal pjäser i rad ned med ett. else break; // Om inte samma pjäs: sluta kolla åt ned. } if (up + down > MARKERS_TO_WIN) return true; // Om antal pjäser till upp och ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: horisontellt. for (int y = lastMarkerY; y >= 0; y--) { // Kolla alla pjäser vänster. if (board[lastMarkerX][y] == marker) left++; // Om samma pjäs: öka antal pjäser i rad vänster med ett. else break; // Om inte samma pjäs: sluta kolla åt vänster. } for (int y = lastMarkerY; y < BOARD_SIZE; y++) { // Kolla alla pjäser höger. if (board[lastMarkerX][y] == marker) right++; // Om samma pjäs: öka antal pjäser i rad höger med ett. else break; // Om inte samma pjäs: sluta kolla åt höger. } if (left + right > MARKERS_TO_WIN) return true; // Om antal pjäser till höger och vänster är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: diagonalt vänster-upp till höger-ned. for (int x = lastMarkerX, y = lastMarkerY; x >= 0 && y >= 0; x--, y--) { // Kolla alla pjäser vänster-upp. if (board[x][y] == marker) leftUp++; // Om samma pjäs: öka antal pjäser i diagonalen vänster-upp med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen vänster-upp. } for (int x = lastMarkerX, y = lastMarkerY; x < BOARD_SIZE && y < BOARD_SIZE; x++, y++) { // Kolla alla pjäser höger-ned. if (board[x][y] == marker) rightDown++; // Om samma pjäs: öka antal pjäser i diagonalen höger-ned med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen höger-ned. } if (leftUp + rightDown > MARKERS_TO_WIN) return true; // Om antal pjäser diagonalt vänster-upp till höger-ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: diagonalt höger-upp till vänster-ned. for (int x = lastMarkerX, y = lastMarkerY; x >= 0 && y < BOARD_SIZE; x--, y++) { // Kolla alla pjäser höger-upp. if (board[x][y] == marker) rightUp++; // Om samma pjäs: öka antal pjäser i diagonalen höger-upp med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen höger-upp. } for (int x = lastMarkerX, y = lastMarkerY; x < BOARD_SIZE && y >= 0; x++, y--) { // Kolla alla pjäser vänster-ned. if (board[x][y] == marker) leftDown++; // Om samma pjäs: öka antal pjäser i diagonalen vänster-ned med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen vänster-ned. } if (rightUp + leftDown > MARKERS_TO_WIN) return true; // Om antal pjäser diagonalt höger-upp till vänster-ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. return false; // Ingen vinst har hittats, alltså returnerar vi falskt. }

Trädvy Permalänk
Medlem
Plats
Sundsvall
Registrerad
Jan 2008

Jag har läst en och en halv kurs i C++ på universitet och jag känner mig inte sådär jättesäker på att jag skulle klara av att göra det du tänkt dig.

Vill dock minnas att jag höll på med lite programmering på gymnasiet, då i C# och då gjorde jag ett fullt fungerande Yatzy-spel men det var ful kod och mycket dra&släpp i något program, kommer inte ihåg vad det hette.

Som någon nämnde tidigare, sten sax påse är ett mycket enklare spel.
Du skriver in en textrad, t.ex "sten", "sax", eller "påse". När du sedan trycker på enter så slumpar datorn fram en av dom. Du kan till exempel slumpa mellan tre siffror, 0,1,2, där 0 motsvarar sten, 1 sax, 2 påse osv. Om datorn slumpar en etta, kolla om det du skrivit in är samma sak som "sax". Om ja, oavgjort. Om du skrivit in sten, plussa då på ett på din vinsträknare. Om du skrivit in påse, plussa datorns räknare med ett. Om du skrivit in något som inte är "sten", "sax", eller "påse", ge ett felmeddelande och fråga om ny input. Du kan också t.ex ha en exit-fras som avslutar loopen. T.ex om du skriver "EXIT" så skrivs slutresultatet ut och programmet avslutas.

Detta borde inte vara allt för svårt att göra. Du behöver typ en do-while loop, några if-satser, samt en randomfunktion. Do-while loop och if-satser är saker du kan och bör lära dig. Att slumpa fram siffra kan du googla hur man gör, alternativt fråga din lärare. Men kom ihåg att slumpfunktionen använder en seed och använder du samma hela tiden så kan du få resultat som inte är så slumpmässiga. Det kan därför vara smart att ändra seeden efter datorns klocka, då får du en bättre randomfunktion. Du kan kolla här t.ex http://www.cplusplus.com/reference/cstdlib/rand/

O2+ODAC - Denon AH-D2000 - Koss Porta Pro
Harman Kardon HK3490 - Had Oy högtalare - 2st Eminence LAB12 slutna baslådor drivna av Behringer iNuke NU6000 MiniDSP och UMIK-1
Min musik/ljudblogg - Phimusic

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

@Kalium: Jag tror faktiskt vi kan strunta i seed till slumptalen. Det är överkurs på den här nivån.

Trädvy Permalänk
Medlem
Registrerad
Okt 2013

Som flera andra har sagt verkar den här uppgiften väldigt omfattande för en gymnasiekurs. Jag läser till civilingenjör och som en del i vår första programmeringskurs skulle vi göra ett spel (yatzy) men vi var då fyra personer och vi hade 2 månader på oss.

Corsair 350D │ 4790k 4,6ghz │ H100i med 2 GT 800rpm │ Asus Maximus VII Gene m-atx│ Sapphire r9 290 tri-x 4 Gb │ Vengeance pro 8gb 1600 │ EVGA supernova G2 750w │Samsung 840 evo 120gb & crucial mx100 256gb │ Barracuda 2tb │ BenQ xl2411z 144hz & AOC q2963pm 21:9 29" 2560x1080 oc'ad till 75Hz │ Razer deathadder chroma & Steelseries 6Gv2 & hyperX Cloud │

LG G4 | Ipad Air | Macbook pro retina 13,3 early 2015 |

Trädvy Permalänk
Medlem
Plats
Sundsvall
Registrerad
Jan 2008
Skrivet av Ingetledigtnamn:

@Kalium: Jag tror faktiskt vi kan strunta i seed till slumptalen. Det är överkurs på den här nivån.

Fast att lägga till en rad kod är väl inte speciellt överkurs?

srand (time(NULL));

O2+ODAC - Denon AH-D2000 - Koss Porta Pro
Harman Kardon HK3490 - Had Oy högtalare - 2st Eminence LAB12 slutna baslådor drivna av Behringer iNuke NU6000 MiniDSP och UMIK-1
Min musik/ljudblogg - Phimusic

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Jan 2013

Ni skrämde iväg tjejen

PS4 & Macbook Pro.

Utlandssvensk sedan många år. Citera för svar.

Trädvy Permalänk
Medlem
Plats
åkersberga, Täby
Registrerad
Jun 2004

Behöver inte vara svårt. Men kommer förmodligen ta lite tid

Som någon ovan sa.

Gör en spelplan som ser ut såhär:

- - - - -
- - - - -
- - - - -
- - - - -
- - - - -

Ersätt strecken med A & B när spelare eller dator lägger en bricka.

Lägg allt i en whileloop, tills någon vinner.

Jag hade skapat spelplanen med Arrayer & jämfört vilken plats i Arrayen som är upptagen av vem.

Är en plats i arrayen upptagen av spelare 1 tilldelar jag platsen i arrayen värdet 1. Är platsen upptagen av spelare 2 tilldelar jag platsen värdet 2.

Sedan klurar man ut någon funktion som tar reda på vilka som ligger jämte varandra.

Dator 1.
FX 8350 4.7Ghz | 24GB ram | MSI Radeon RX 480 | Kingston SSD | Fractal design R2.0 | PSU : Fractal 650W
Dator 2 (Bärbar). HP Folio 9470m

Trädvy Permalänk
Medlem
Plats
Sundsvall
Registrerad
Jun 2011

@gustavwth:

Helt OT men använd gärna spoilertaggen i framtiden så inte inläggen blir flera meter långa.
Får träningsvärk i scrollfingret

// ---------------------------- // | Fem-I-Rad Spel Med Musen | // ---------------------------- #include <windows.h> // Händelser. #include <stdio.h> // Inmatning. #include <stdlib.h> // Slumpgenerator. #include <time.h> // Klockan.(används bara av slumpgeneratorn) // ------------------------------------------------------------------------------------------------------ // ---------------------- HÄNDELSE-KOD FÖRBEREDELSER ---------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // Definierar konstanter till fönster och händelser. #define MOUSE_PRESSED_OR_RELEASED 0 // 0 betyder att knapp är tryckt eller släppt. #define EVENT_BUFFER_SIZE 128 // Antal händelser som kan lagras i bufferten för händelser. // Globala variabler till fönster och händelser. INPUT_RECORD eventInputBuffer[EVENT_BUFFER_SIZE]; // Händelse Buffert DWORD nrOfEvents; // Antal händelser som ligger i händelse bufferten. HANDLE consoleInputHandle = GetStdHandle(STD_INPUT_HANDLE); // Hämtar hantaget till standard input som hör till konsollen. HANDLE consoleOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);// Hämtar hantaget till standard output som hör till konsollen. // Funktioner för händelsehantering. void initConsole(); // Ställer in konsollen för att hantera händelser. void clearScreen(); // Rensar skärmen och ställer in konsollen för att hantera händelser på nytt. void eventHandler(); // Läser in och hanterar händelser. void keyboardEventHandler(KEY_EVENT_RECORD); // Hanterar tangentbords-tryckningar. void mouseEventHandler(MOUSE_EVENT_RECORD); // Hanterar mus-tryckningar. // ------------------------------------------------------------------------------------------------------ // ---------------------- SPEL-KOD FÖRBEREDELSER -------------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // Vi börjar med att definiera konstanter för spelet. #define BOARD_SIZE 10 // Storleken på spelplanen. #define MARKERS_TO_WIN 5 // Antal pjäser i rad som krävs för att vinna. #define EMPTY_MARKER '-' // Bokstav som representerar en tom ruta på spelplanen. #define PLAYER_1_MARKER 'X' // Boksatav som representerar den första spelarens pjäser. #define PLAYER_2_MARKER 'O' // Boksatav som representerar den andra spelarens pjäser. // Vi definierar de olika lägen spellet kan befinna sig i. #define GAME_STATE_START_MENU 1 // Spelet kan vara i huvudmeny. #define GAME_STATE_HUMAN 2 // Det kan vara en människas tur att spela. #define GAME_STATE_COMPUTER 3 // Det kan vara en dators tur att spela. #define GAME_STATE_END 4 // Spelet är över. #define START_MENU_OPTION_MULTIPLAYER 1 // Vilken rad på menyn knappen för multiplayer ligger på. #define START_MENU_OPTION_SINGLEPLAYER 2 // Vilken rad på menyn knappen för singleplayer ligger på. // Deklarera Globala variabler som spelet använder. char currentGameState = GAME_STATE_START_MENU; // Variabel för nuvarande spelläge, spelet börjar på start menyn. char board[BOARD_SIZE][BOARD_SIZE]; // 2-Dimensionell array av bokstäver som representerar spelplanen, bokstäverna kan antingen vara "EMPTY_MARKER", "PLAYER_1_MARKER" eller "PLAYER_2_MARKER". int lastMarkerX, lastMarkerY; // Vi lagrar positionen för den senaste placerade spelpjäsen, därför att vi kan då enkalre testa om en spelare har vunnit. bool isMultiplayer; // Variabel som bestämmer om spelet är mot andra spelare eller mot datorn. char currentPlayer = PLAYER_1_MARKER; // Håller reda på vems tur det är, börjar på spelare ett. // Funktioner som spelet använder sig utav. void initBoard(); // Nollställa spelplanen. bool placeMarker(int x, int y, char marker); // Placera spelpjäs. void humanPlay(int x, int y); // Människans drag. bool computerPlay(char marker); // Datorns drag. bool checkWin(); // Kolla om senaste draget gjorde att spelaren vann. void gameRound(bool *done); // En runda på spelet. void startMenu(int y); // Startmeny. // Grafik funktioner. void printMenu(); // Skriv ut startmeny. void printBoard(); // Skriva ut spelplanen. void printVictory(); // Skriv ut vem som vann. // ------------------------------------------------------------------------------------------------------ // ---------------------- Huvudfunktionen som körs när programmet startas. ------------------------------ // ------------------------------------------------------------------------------------------------------ int main(){ initConsole(); // Ställer in konsollen för att hantera händelser. printMenu(); // Kolla om vi ska köra mot människa eller dator. printBoard(); // Ritar ut spelplanen. bool done = false; // Variabel som avgör om programmet ska avslutas. while (!done) { // Själva programloopen körs tills done är sant. eventHandler(); // Hanterar händelser som uppstår från användaren. gameRound(&done); // Kör En runda på spelet. } printVictory(); // Skriv ut vem som vann. system("pause"); // Pausa så att inte konsollen försvinner direkt. return 0; } // ------------------------------------------------------------------------------------------------------ // ---------------------- HÄNDELSE-KOD ------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------ // Läser in händelser som uppstår och vidarebefodrar dem till korrekt händelsehanterare. void eventHandler() { ReadConsoleInput(consoleInputHandle, eventInputBuffer, EVENT_BUFFER_SIZE, &nrOfEvents); // Hämtar händelser till bufferten: eventInputBuffer, och räknar antalet händelser till: nrOfEvents. for (int i = 0; i < nrOfEvents; i++) { // För varje händelse. switch (eventInputBuffer[i].EventType) { // Kolla vilken typ av händelse. case KEY_EVENT: // Om det är tangentbordstrckningar. keyboardEventHandler(eventInputBuffer[i].Event.KeyEvent); // Låt tangentbordshanteraren hantera händelsen. break; case MOUSE_EVENT: // Om det är tangentbordstrckningar. mouseEventHandler(eventInputBuffer[i].Event.MouseEvent); // Låt mushanteraren hantera händelsen. break; } } } // Tangentbordshändelsehanteraren hanterar knapptrckningar på tangentbordet. void keyboardEventHandler(KEY_EVENT_RECORD keyEvent) { if (!keyEvent.bKeyDown) { // Om vi släpper en tangent på skrivbordet. // Nu har vi inget som händer här, men här kan man lägga till flera händelser för att bygga vidare om man vill använda tangentbordet. } } // Mushändelsehanteraren hanterar knapptrckningar på musen. void mouseEventHandler(MOUSE_EVENT_RECORD mouseEvent) { if (mouseEvent.dwEventFlags == MOUSE_PRESSED_OR_RELEASED) { // Om musknappen trcks eller släpps. if (mouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) { // Om det är vänstra musknappen. const int mousePosX = mouseEvent.dwMousePosition.X; // Hämta muspekarens X position i konsollen. const int mousePosY = mouseEvent.dwMousePosition.Y; // Hämta muspekarens Y position i konsollen. int col, row; switch (currentGameState) { // Kolla spelläge. case GAME_STATE_HUMAN: // Om det är spelarens tur. col = mousePosX / 2; // Vi måste räkna med att vi ritar ut spelplanen med mellanrum. row = mousePosY; // Inget mellanrum mellan rader. humanPlay(row, col); // Spela pjäsen på den tryckta positionen. break; case GAME_STATE_START_MENU: // Om vi är i startmenyn. startMenu(mousePosY); // Testa startmenyn. break; } } } } // Initiera konsollen genom att tillåta händelser och ta bort markören. void initConsole() { SetConsoleMode(consoleInputHandle, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); // Vi aktiverar händelser till konsol-fönstret. CONSOLE_CURSOR_INFO cursor; cursor.bVisible = false; cursor.dwSize = 1, // Skapa en ny onsynlig markör. SetConsoleCursorInfo(consoleOutputHandle, &cursor); // Aktivera den onsynliga markören till konsolen, så vi inte ser en blinkande markör. } // ------------------------------------------------------------------------------------------------------ // ---------------------- GRAFIK-KOD -------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // Skriva ut spelplanen. void printBoard() { for (int i = 0; i < BOARD_SIZE; i++) { // Gå igenom alla rader. for (int j = 0; j < BOARD_SIZE; j++) // Gå igenom alla kolumner. printf("%c ", board[i][j]); // Skriv ut spelmarkörerna på spelplannen. printf("\n"); // Byt rad. } } // Kolla om användaren vill spela mot en annan spelare, eller mot datorn. void printMenu() { printf("Select gamemode with left mouse button.\n");// Skriv ut val av spelläge. printf("Human vs human.\n"); // Skriv ut Alternativ 1, två spelare mot varandra. printf("Human vs computer.\n"); // Skriv ut Alternativ 2, spelare mot dator. } // Skriv ut vem som vann. void printVictory() { printf("Congratualtions Player %c, you won!\n", board[lastMarkerX][lastMarkerY]); } // Rensar skärmen void clearScreen() { system("cls"); // Rensar skärmen. initConsole(); // Konsollen måste tillåta händelser. } // ------------------------------------------------------------------------------------------------------ // ---------------------- SPEL-KOD ---------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------------ // En runda av spelet. void gameRound(bool *done) { switch (currentGameState) { // Kolla vilket spelläge spelet är i. case GAME_STATE_HUMAN: // Människans spel hanteras separat av händelser. break; case GAME_STATE_COMPUTER: // Om det är datorns tur att spela. while (!computerPlay(currentPlayer)); // Låt datorn göra sitt drag. clearScreen(); // Rensa skärmen. printBoard(); // Rita ut spelplanen. currentPlayer = currentPlayer == PLAYER_1_MARKER ? PLAYER_2_MARKER : PLAYER_1_MARKER; // Här byter vi till nästa spelare. currentGameState = GAME_STATE_HUMAN; // låt människan spela. if (checkWin()) currentGameState = GAME_STATE_END; // Kolla om vinst. break; case GAME_STATE_END: // Om spelet är slut. *done = true; // Avsluta spelet. break; } } // Om människa försöker spela. void humanPlay(int x, int y) { if (currentGameState == GAME_STATE_HUMAN) { if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE) { // Försök endast placera om vi är innanför banan. if (placeMarker(x, y, currentPlayer)) { // Om placering lyckades. clearScreen(); // Rensa skärmen. printBoard(); // Rita ut spelplanen. currentPlayer = currentPlayer == PLAYER_1_MARKER ? PLAYER_2_MARKER : PLAYER_1_MARKER; // Här byter vi till nästa spelare. if (!isMultiplayer) currentGameState = GAME_STATE_COMPUTER; // Om det är singleplayer, låt datorn spela. if (checkWin()) currentGameState = GAME_STATE_END; // Kolla om vinst. } } } } // En dators tur att spela. Här kan man vidareutveckla en strategi åt datorn, nu kör den slumpvis. bool computerPlay(char marker) { int x, y; // Variabler Rad och kolumn som datorn vill placera sin pjäs på. x = rand() % BOARD_SIZE; // Datorn väljer en slupvis rad på spelplanen. y = rand() % BOARD_SIZE; // Datorn väljer en slupvis kolumn på spelplanen. return placeMarker(x, y, marker); // Placerar pjäsen på spelplanen. } // Placera spelpjäs. bool placeMarker(int x, int y, char marker) { if (board[x][y] != EMPTY_MARKER) return false; // Om det redan finns än pjäs på rutan, returnera falskt. (det gick ej att placera pjäsen). board[x][y] = marker; // Placera spelpjäsen på brädet. lastMarkerX = x; // Vi lägger undan raden för pjäsen i den globala variabeln för senast placerade pjäs rad position. lastMarkerY = y; // Vi lägger undan kolumnen för pjäsen i den globala variabeln för senast placerade pjäs kolumn position. return true; } // Nollställa spelplanen. void initBoard() { for (int i = 0; i < BOARD_SIZE; i++) // Gå igenom alla rader. for (int j = 0; j < BOARD_SIZE; j++) // Gå igenom alla kolumner. board[i][j] = EMPTY_MARKER; // Placera en tom markör på spelplanen. } // Testa att klicka på en rad i startmenyn. void startMenu(int y) { switch (y) { // Kolla rad som klickades på. case START_MENU_OPTION_MULTIPLAYER: // Om multiplayer är valt. currentGameState = GAME_STATE_HUMAN;// Gå över till spelläget. isMultiplayer = true; // Välj multiplayer. initBoard(); // Nollställa spelplanen. clearScreen(); // Rensa skärmen printBoard(); // Rita ut spelplanen. break; case START_MENU_OPTION_SINGLEPLAYER: // Om singleplayer är valt. currentGameState = GAME_STATE_HUMAN;// Gå över till spelläget isMultiplayer = false; // Välj singleplayer. initBoard(); // Nollställa spelplanen. clearScreen(); // Rensa skärmen printBoard(); // Rita ut spelplanen. break; } } // Kollar om den senaste placerade pjäsen gjorde att spelaren vann. bool checkWin() { char marker = board[lastMarkerX][lastMarkerY]; // Senaste spelarens spelpjäs. int left = 0, right = 0, up = 0, down = 0; // Antal likadana pjäser längs olika riktningar. int leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0; // Undersök vinst: vertikalt. for (int x = lastMarkerX; x >= 0; x--) { // Kolla alla pjäser upp. if (board[x][lastMarkerY] == marker) up++; // Om samma pjäs: öka antal pjäser i rad upp med ett. else break; // Om inte samma pjäs: sluta kolla åt upp. } for (int x = lastMarkerX; x < BOARD_SIZE; x++) { // Kolla alla pjäser ned. if (board[x][lastMarkerY] == marker) down++; // Om samma pjäs: öka antal pjäser i rad ned med ett. else break; // Om inte samma pjäs: sluta kolla åt ned. } if (up + down > MARKERS_TO_WIN) return true; // Om antal pjäser till upp och ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: horisontellt. for (int y = lastMarkerY; y >= 0; y--) { // Kolla alla pjäser vänster. if (board[lastMarkerX][y] == marker) left++; // Om samma pjäs: öka antal pjäser i rad vänster med ett. else break; // Om inte samma pjäs: sluta kolla åt vänster. } for (int y = lastMarkerY; y < BOARD_SIZE; y++) { // Kolla alla pjäser höger. if (board[lastMarkerX][y] == marker) right++; // Om samma pjäs: öka antal pjäser i rad höger med ett. else break; // Om inte samma pjäs: sluta kolla åt höger. } if (left + right > MARKERS_TO_WIN) return true; // Om antal pjäser till höger och vänster är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: diagonalt vänster-upp till höger-ned. for (int x = lastMarkerX, y = lastMarkerY; x >= 0 && y >= 0; x--, y--) { // Kolla alla pjäser vänster-upp. if (board[x][y] == marker) leftUp++; // Om samma pjäs: öka antal pjäser i diagonalen vänster-upp med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen vänster-upp. } for (int x = lastMarkerX, y = lastMarkerY; x < BOARD_SIZE && y < BOARD_SIZE; x++, y++) { // Kolla alla pjäser höger-ned. if (board[x][y] == marker) rightDown++; // Om samma pjäs: öka antal pjäser i diagonalen höger-ned med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen höger-ned. } if (leftUp + rightDown > MARKERS_TO_WIN) return true; // Om antal pjäser diagonalt vänster-upp till höger-ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. // Undersök vinst: diagonalt höger-upp till vänster-ned. for (int x = lastMarkerX, y = lastMarkerY; x >= 0 && y < BOARD_SIZE; x--, y++) { // Kolla alla pjäser höger-upp. if (board[x][y] == marker) rightUp++; // Om samma pjäs: öka antal pjäser i diagonalen höger-upp med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen höger-upp. } for (int x = lastMarkerX, y = lastMarkerY; x < BOARD_SIZE && y >= 0; x++, y--) { // Kolla alla pjäser vänster-ned. if (board[x][y] == marker) leftDown++; // Om samma pjäs: öka antal pjäser i diagonalen vänster-ned med ett. else break; // Om inte samma pjäs: sluta kolla åt diagonalen vänster-ned. } if (rightUp + leftDown > MARKERS_TO_WIN) return true; // Om antal pjäser diagonalt höger-upp till vänster-ned är störe än kravet för vinst (större eftersom mitten pjäsen räknas två gånger), då är det vinst och vi returnerar sant. return false; // Ingen vinst har hittats, alltså returnerar vi falskt. }

Dold text

CITERA OM DU VILL HA SVAR! :)

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008
Skrivet av Kalium:

Fast att lägga till en rad kod är väl inte speciellt överkurs?

srand (time(NULL));

Nej, en rad kod är inte så mycket för dig eller mig, men när vi går från nivån "ingen aning" är varje extra sak att ta hänsyn till ytterligare ett hinder att passera på vägen till målsnöret. Som van programmerare kan man tänka bort saker: äh, det där fixar jag senare, men som nybörjare kan för många småsaker verka oöverstigliga. När TS tror att hen är klar kan vi börja rabbla upp alla extra saker att tänka på (dokumentation, optimering, unit testing ). Om StenSaxPåse 0.99 alltid väljer samma sekvens spelar ingen roll. Om programmet funkar är det fullt tillräckligt. Toppen!!! Sedan kan vi uppmuntra stegvisa förbättringar, men spar det tills grunderna funkar.

Trädvy Permalänk
Medlem
Plats
Götet, typ
Registrerad
Okt 2004

En ännu enklare kanske är att göra ett "gissa talet" -spel där datorn slumpar ett tal och du gissar vad det är och den säger om det var för högt eller för lågt. Jag tycker det är ganska bra för en nybörjare.

/M

Trädvy Permalänk
Medlem
Plats
Sundsvall
Registrerad
Jan 2008
Skrivet av Marowak:

En ännu enklare kanske är att göra ett "gissa talet" -spel där datorn slumpar ett tal och du gissar vad det är och den säger om det var för högt eller för lågt. Jag tycker det är ganska bra för en nybörjare.

Det var typ det första eller andra programmet vi gjorde i grundkursen i C++ nu på universitetet. Den kursen var tänkt för folk som aldrig programmerat förut så det är nog ett lämpligt projekt för TS.

O2+ODAC - Denon AH-D2000 - Koss Porta Pro
Harman Kardon HK3490 - Had Oy högtalare - 2st Eminence LAB12 slutna baslådor drivna av Behringer iNuke NU6000 MiniDSP och UMIK-1
Min musik/ljudblogg - Phimusic