• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kółko i krzyżyk

VPS Starter Arubacloud
0 głosów
472 wizyt
pytanie zadane 10 września 2016 w C i C++ przez Antero00 Gaduła (3,670 p.)

Witam, postanowiłem sobie napisać własny kod gry kółko i krzyżyk, ale mam problem z funkcją sprawdzającą czy gracz wygrał. Zależało mi, aby w przypadku kiedy gracz ułoży w kolumnie, wierszu bądź po skosie gra automatycznie się kończyła z odpowiednim komunikatem.

Prosiłbym o jakieś wskazówki.

Wiem, że kod nie jest idealny, ale proszę o wyrozumiałość.

Oto kod:

#include <iostream>
#include <cstdlib>
#include <ctime>

void show_map(char board[])
{
	system("cls");
	std::cout << " Kolko i krzyzyk " << std::endl << "\nGracz 1 = (X) \t Gracz 2 = (O)\n\n";

	for (int i = 1; i <= 9; i++)
	{
		std::cout << " " << board[i] << " ";
		if (i % 3)
			std::cout << "|";
		else if (i != 9)
			std::cout << "\n---+---+---\n";
		else std::cout << std::endl;
	}
}

bool win_game(char board[], char player)
{
	bool game = false;

	for (int i = 0; i <= 6; i += 3) // poziomo
	{
		if ((board[i] == player) && (board[i + 1] == player) && (board[i + 2] == player))
			game = true;
		break;
	}
	for (int j = 0; j < 3; j += 3) // pionowo
	{
		if ((board[j] == player) && (board[j + 3] == player) && (board[j + 6] == player))
		{
			game = true;
			break;
		}
	}
	// skos
	/*
	if ((board[0] == player) && (board[4] == player) && (board[8] == player))
		...
	
	if ((board[2] == player) && (board[4] == player) && (board[6] == player))
		...
	*/
	if (game)
	{
		show_map(board);
		std::cout << " Gracz " << player << " wygrywa" << std::endl;
		return true;
	}

	return false;
}

bool tie_game(char board[])
{
	for (int i = 0; i < 9; i++)
	{
		if (board[i] == ' ')
			return false;
	}

	show_map(board);
	std::cout << "Remis " << std::endl;
	return true;
}

void move_player(char board[], char &player)
{
	int sign;

	show_map(board);
	std::cout << "\n Gracz " << player << ": twoj ruch : ";
	std::cin >> sign;
	std::cout << "----------------------";
	
	if ((sign >= 1) && (sign <= 9) && (board[sign] == ' '))
		board[sign] = player;
	player = (player == 'O') ? 'X' : 'O';
}
int main()
{
	srand(time(NULL));

	char map[9], p;
	
	// 1 == 'O'
	// 2 == 'X

	for (int i = 1; i <= 9; i++) 
		map[i] = ' ';

	char start = rand() % 2 + 1;
	if (start == 1)
		p = 'O';
	else if (start == 2)
		p = 'X';
	
	while ((!win_game(map, 'X')) && (!win_game(map, 'O')) && (!tie_game(map)))
		move_player(map, p);
	getchar(); getchar();
	return 0;
}

 

2 odpowiedzi

0 głosów
odpowiedź 10 września 2016 przez Jonki Dyskutant (8,180 p.)

Nie dysponuję teraz kompilatorem do C++, ale lepiej byłoby Tobie zrobić tablicę dwuwymiarową, potem rysować ją podwójną pętlą for. Tą Twoją tablicę trudno jest sprawdzić jedną pętlą. We wszystkie strony to bardzo skomplikowanie wyglądałoby. Jakbyś miał tablicę dwuwymiarową, to mógłbyś jedną pętlą sprawdzać np. poziomo, a drugą pionowo i kolejną na ukos.

Kiedyś pisałem coś takiego w Javie. Może Tobie się przydać.

import java.util.Scanner;
import java.util.Random;

public class TicTacToe {
	
	static Scanner input = new Scanner(System.in);
	
	static String charWinner;
	
	public static void main(String[] args) {
		
		int x, y;
		Random randomNumber = new Random();
		int end = 0;
		
		String charUser = " X ", charBot = " O ";
		
		String[][] tab = new String[4][4];
		
		
		tab[0][0] = "   ";
		tab[0][1] = " 1 ";
		tab[0][2] = " 2 ";
		tab[0][3] = " 3 ";
		
		tab[1][0] = " 1 ";
		tab[1][1] = "   ";
		tab[1][2] = "   ";
		tab[1][3] = "   ";
		tab[2][0] = " 2 ";
		tab[2][1] = "   ";
		tab[2][2] = "   ";
		tab[2][3] = "   ";
		tab[3][0] = " 3 ";
		tab[3][1] = "   ";
		tab[3][2] = "   ";
		tab[3][3] = "   ";
		
		
		do {
			for(int i = 0; i < 4; ++i) {
				for(int j = 0; j < 4; ++j) {
					System.out.print(tab[i][j]);
				}
				System.out.println("");
			}
		
			System.out.println("");
			System.out.println("");
			System.out.print("Enter a value X: ");
			x = input.nextInt();
			System.out.print("Enter a value Y: ");
			y = input.nextInt();
			
			if(checkPosition(x, y, tab)) {
				tab[y][x] = charUser;
			} else {
				continue;
			}
			
			if(endGame(tab)) {
				end = 1;
			}
			
			while(true) {
				x = 1+randomNumber.nextInt(3);
				y = 1+randomNumber.nextInt(3);
				
				if(checkPositionBot(x, y, tab)) {
					tab[y][x] = charBot;
					break;
				} else {
					continue;
				}
			}
		}while(end != 1);
		
		System.out.println("");System.out.println("");
		
		for(int i = 0; i < 4; ++i) {
			for(int j = 0; j < 4; ++j) {
				System.out.print(tab[i][j]);
			}
			System.out.println("");
		}
		
		if(charWinner.equals(charUser.trim())) {
			System.out.println("");
			System.out.println("YOU WON!");
		} else {
			System.out.println("");
			System.out.println("YOU LOST!");
		}
		
	}
	
	public static boolean checkPosition(int x, int y, String[][] tab) {
		
		if(tab[y][x].equals(" X ") || tab[y][x].equals(" O ")) {
			System.out.println("");
			System.err.println("This position is occupied.");
			
			return false;
		} else {
			return true;
		}
	}
	
	public static boolean checkPositionBot(int x, int y, String[][] tab) {
		
		if(tab[y][x].equals(" X ") || tab[y][x].equals(" O ")) {
			return false;
		} else {
			return true;
		}
	}
	
	 static boolean endGame(String[][] tab) {
		
		 if(tab[1][1].equals(" X ") && tab[1][2].equals(" X ") && tab[1][3].equals(" X ") 
		       || tab[2][1].equals(" X ") && tab[2][2].equals(" X ") && tab[2][3].equals(" X ")
		       || tab[3][1].equals(" X ") && tab[3][2].equals(" X ") && tab[3][3].equals(" X ")
		       || tab[1][1].equals(" X ") && tab[2][1].equals(" X ") && tab[3][1].equals(" X ")
		       || tab[1][2].equals(" X ") && tab[2][2].equals(" X ") && tab[3][2].equals(" X ")
		       || tab[1][3].equals(" X ") && tab[2][3].equals(" X ") && tab[3][3].equals(" X ")
		       || tab[1][1].equals(" X ") && tab[2][2].equals(" X ") && tab[3][3].equals(" X ")
		       || tab[1][3].equals(" X ") && tab[2][2].equals(" X ") && tab[3][1].equals(" X ")) {
			 
			 charWinner = "X";
			 
			 return true;
		 } else if(tab[1][1].equals(" Y ") && tab[1][2].equals(" Y ") && tab[1][3].equals(" Y ") 
		       || tab[2][1].equals(" Y ") && tab[2][2].equals(" Y ") && tab[2][3].equals(" Y ")
		       || tab[3][1].equals(" Y ") && tab[3][2].equals(" Y ") && tab[3][3].equals(" Y ")
		       || tab[1][1].equals(" Y ") && tab[2][1].equals(" Y ") && tab[3][1].equals(" Y ")
		       || tab[1][2].equals(" Y ") && tab[2][2].equals(" Y ") && tab[3][2].equals(" Y ")
		       || tab[1][3].equals(" Y ") && tab[2][3].equals(" Y ") && tab[3][3].equals(" Y ")
		       || tab[1][1].equals(" Y ") && tab[2][2].equals(" Y ") && tab[3][3].equals(" Y ")
		       || tab[1][3].equals(" Y ") && tab[2][2].equals(" Y ") && tab[3][1].equals(" X ")) {
			 
			 charWinner = "Y";
		 
		 	 return true;
	 	} else {
	 		return false;
	 	}
	 }
	
}
1
komentarz 10 września 2016 przez Antero00 Gaduła (3,670 p.)

Tą Twoją tablicę trudno jest sprawdzić jedną pętlą.

A napisanie 

if'a

dla każdego wariantu wygrywającego ? Ma to sens ?

0 głosów
odpowiedź 12 września 2016 przez Antero00 Gaduła (3,670 p.)

Tak wygląda gotowy kod, co można by zrobić lepiej ?

#include <iostream>
#include <cstdlib>
#include <ctime>

void show_map(char board[3][3])
{
    system("cls");
    std::cout << " Kolko i krzyzyk " << std::endl << "\nGracz 1 = (X) \t Gracz 2 = (O)\n\n";
    
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
        {
            if (board[i][j] == ' ')
                std::cout << i << j;
            std::cout<< "" << board[i][j] << "";
            if (j < 2)
                std::cout << "|";
            else if (i < 2)
                std::cout << "\n---+---+---\n";
            else std::cout << std::endl;
            
        }
}

bool win_game(char board[3][3], char player)
{
    bool test = false;
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j += 3)
        {
            //poziomo
            if ((board[i][j] == player) && (board[i][j + 1] == player) && (board[i][j + 2] == player))
            {
                test = true;
                break;
            }
            if ((board[i][j] == player) && (board[i][j + 1] == player) && (board[i][j + 2] == player))
            {
                test = true;
                break;
            }
            if ((board[i][j] == player) && (board[i][j + 1] == player) && (board[i][j + 2] == player))
            {
                test = true;
                break;
            }
            //pionowo

            if ((board[i][j] == player) && (board[i + 1][j] == player) && (board[i + 2][j] == player))
            {
                test = true;
                break;
            }
            if ((board[i - 1][j + 1] == player) && (board[i][j + 1] == player) && (board[i + 1][j + 1] == player))
            {
                test = true;
                break;
            }
            if ((board[i - 2][j + 2] == player) && (board[i - 1][j + 2] == player) && (board[i][j + 2] == player))
            {
                test = true;
                break;
            }
            // skos

            if ((board[i][j] == player) && (board[i + 1][j + 1] == player) && (board[i + 2][j + 2] == player))
            {
                test = true;
                break;
            }
            if ((board[i][j + 2] == player) && (board[i + 1][j + 1] == player) && (board[i + 2][j] == player))
            {
                test = true;
                break;
            }
        }

    if (test)
    {
        show_map(board);
        std::cout << "Gracz " << player << " wygrywa " << std::endl;
        return true;
    }

    return false;
}

bool tie_game(char board[3][3])
{
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
        {
            if (board[i][j] == ' ')
                return false;
        }
    show_map(board);
    std::cout << " Remis " << std::endl;
    return true;
}

void move_player(char board[3][3], char &player)
{
    int x, y;

    show_map(board);
    std::cout << "\nGRACZ " << player << " : Podaj wspolrzedne XY oddzielone spacja:  ";
    std::cin >> x >> y;
    std::cout << "-----------------------\n\n";
    if ((x, y >= 0) && (x, y <= 2) && (board[x][y] == ' '))
        board[x][y] = player;
    player = (player == 'O') ? 'X' : 'O';
}
int main()
{
    srand(time(NULL));

    char map[3][3], p;
    
    // 1 == 'O'
    // 2 == 'X

    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            map[i][j] = ' ';
            
    char start = rand() % 2 + 1;
    if (start == 1)
        p = 'O';
    else if (start == 2)
        p = 'X';
    
    while ((!win_game(map, 'X')) && (!win_game(map, 'O')) && (!tie_game(map)))
        move_player(map, p);
    getchar(); getchar();
    return 0;
}

 

Ma ktoś pomysł jak zrobić, aby plansza przy wpisywaniu współrzędnych nie "rozjeżdżała się"  ?

1
komentarz 12 września 2016 przez JAKUBW Nałogowiec (33,470 p.)

To chyba nie działa tak jak chcesz:

if ((x, y >= 0) && (x, y <= 2) && (board[x][y] == ' '))

warning: left operand of comma operator has no effect [-Wunused-value]|

Ogólnie to dał bym tu kontrolę błędów 

1
komentarz 12 września 2016 przez JAKUBW Nałogowiec (33,470 p.)

A tu po co dodajesz 1 i sprawdzasz 2 raz?

char start = rand() % 2 + 1;
    if (start == 1)
        p = 'O';
    else if (start == 2)
        p = 'X';

Wystarczy:

p = (rand() % 2 == 1)? 'O':'X';

 

Podobne pytania

0 głosów
2 odpowiedzi 1,161 wizyt
pytanie zadane 13 stycznia 2019 w C i C++ przez pysiek Początkujący (280 p.)
+1 głos
0 odpowiedzi 635 wizyt
0 głosów
0 odpowiedzi 1,972 wizyt
pytanie zadane 11 listopada 2016 w C i C++ przez Undisputed Gaduła (3,040 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...