Pętla Graczy

0

Piszę grę w której 2 lub więcej graczy musi na zmianę dokonywać ruchu. W jaki sposób można to rozwiązać? Nie mam kompletnie pomysłu. Musi się to odbywać cały czas. Myślałem o użyciu do while ale to bez sensu raczej.

Nie wiem też jak rozwiązać właśnie "dynamicznie" ilość graczy. Aktualnie statycznie stworzyłem 2 obiekty graczy i na tym staram się pracować jednak chciałbym aby działo się to automatycznie po wyborze ilości graczy.

ogólny zamysł:
gracz 1 -> rzut koscia - > ruch na dany obszar -> wykonanie polecenia -> koniec tury -> gracz 2 -> rzut koscia itp..

0

Taki prosty przykład z kółko i krzyżyk

 if (cureentlyPlayer == true) {
                    clickedButton.setText("X");
                    cureentlyPlayer = false;
 
 
                } else {
 
                    clickedButton.setText("O");
                    cureentlyPlayer = true;
0

wystarczy że każdy player będzie wiedział kto jest po nim i będzie miał pole Player nextPlayer
po ruchu w pętli programu ustawiasz currentPlayer = currentPlayer.nextPlayer i tyle

może to być też tablica i operacjami ruch modulo ilość_graczy wybrać gracza ale to mniej obiektowe podejście

1
import java.io.*;

class Ideone
{
	public static void main(String[] args)
	{
		final int playersCount = 4, testsCount = 4*6+1;
		for(int i = 0; i < testsCount; ++i)
			System.out.println("Player id: "+i%playersCount);
	}
}

out:

Player id: 0
Player id: 1
Player id: 2
Player id: 3
Player id: 0
Player id: 1
Player id: 2
Player id: 3
Player id: 0
Player id: 1
Player id: 2
Player id: 3
Player id: 0
Player id: 1
Player id: 2
Player id: 3
Player id: 0
Player id: 1
Player id: 2
Player id: 3
Player id: 0
Player id: 1
Player id: 2
Player id: 3
Player id: 0
0

Dzięki wielkie :)

spartanPAGE czyli muszę zrobić taką klasę jak napisałeś + dodać do klasy player pole które będzie zawierać ID gracza i metodę zwrotu tej wartości tak?

0

Cała magia w tym, że nie musisz nic. ID graczy moze byc jego polozeniem w tablicy, więc w tej sytuacji jest on calkowicie bierny.

0

Pojawił się kolejny problem. Chce aby po rzucie kostką wynik rzutu + aktualna pozycja ( liczba całkowita ) były zapisywane w obiekcie ruch.
tzn. stoje na polu nr. 2 i wyrzuciłem 5 , więc przesuwam się na pole o numerze 7 i Numer aktualnej pozycji zmienia się na 7 itd. az do 40, po czym zmienna się zeruje i zaczyna zliczać od 1. I tak w kółko.

Moja klasa ruch. Wywołuje ją przez podanie za n liczby oczek wyrzuconych podczas rzutu.

 class ruch
{
	public ruch(int n)
	{
		LiczbaOczekNaKostce =n;
	}
	
	public int NumerAktualnejPozycji()
	{
	return	NumerAktualnejPozycjiNaPlanszy;
	}
	
	private int NumerAktualnejPozycjiNaPlanszy;
	private int LiczbaOczekNaKostce;
	private static int NumerAktualnejPozycji;
	
	static
	{
		NumerAktualnejPozycji = 1;
	}
	
	{
		NumerAktualnejPozycji += LiczbaOczekNaKostce;
		NumerAktualnejPozycjiNaPlanszy = NumerAktualnejPozycji;
		
	}
}
1

Ten kod to jest kpina

0

Sorry dopiero zaczynam przygodę z Java tak więc proszę o wyrozumiałość. W jaki sposób w takim razie to można rozwiązać?

0

spartanPAGE to ma być eurobussines. No i właśnie podczas pisania kodu znajduję coraz więcej problemów. Głównie właśnie nie wiem jak rozwiązać ten problem z poruszaniem się po planszy i chyba najważniejszy w jaki sposób przypisywać państwa do poszczególnych graczy i sprawdzać które do kogo należy.
Grę robię niestety na razie tylko w konsoli.. Tak wiem że bezsens ale nie mam czasu na zabawę z grafiką( dodam w późniejszym czasie ).

1

Dlaczego zmienną "NumerAktualnejPozycji" definiujesz jako statyczną? Musisz się liczyć wtedy z tym że do każdej instancji czy jak kto woli po polsku egzemplarza obiektu zmienna ta będzie miała taką samą wartość. Nie będziesz miał wtedy możliwości rozgrywania np. 2 gier na raz, a do tego będziesz musiał się męczyć z czyszczeniem jej po każdej rozegranej grze. Moim zdaniem powinieneś stworzyć klasę GameBoard (pol. PlanszaDoGry), w niej trzymać listę graczy, a w obiekcie każdego gracza nr pola na którym się znajduje. Wtedy usuwając referencję do obiektu GameBoard znikną wszystkie wartości, a tworząc jego nową instancję będziesz mógł bezproblemowo zacząć nową grę bez borykania się z zerowaniem wszystkich pól. Do tego do obiektu GameBoard dodałbym booleana np isGameEnded(), który zwracał by odpowiednią wartość w zależności od tego czy którykolwiek gracz jest już po za planszą, jeżeli jest zwracało by tak, jeżeli nie - nie. Na podstawie wartości zwróconej przez tą metodę będziesz mógł zadecydować czy rozpocząć nową grę, czy nie.

public boolean isGameEnded() {
    for(Player p : this.players) {
        if(p.getFieldNumber() >= this.board.getMaxFieldNumber() {
            return true;
        }
    }
    return false;
}

Edit:
Mógłbyś nawet w tej metodzie zwracać gracza, który wygrał i dawać mu np. jakąś nagrode

Edit2: Jak zaczynasz to łap jeszcze poniższe klasy, żeby rozwiać już wszystkie twoje wątpliwości

public class Player {
    // Domyślne gracz jest na starcie, czyli w tym przypadku polu nr. 0
    private int fieldNumber = 0;
    
    public Player() {
    }

    public int getFieldNumber() { return this.fieldNumber; }

    public void move(int fields) {
        this.fieldNumber += fields;
    }
}

public class GameBoard {
    private List<Player> players = new ArrayList<>();
    public Gameboard() {}
    public boolean isGameEnded // Napisane wyżej
}

public class Cube {
    private Random random = new Random();
    public int getFiledsToMove() {
        return random.nextInt(6) + 1;
    }
}
1

Piszę tutaj, bo potrzebuję kolorowania składni.

Dodaj sobie metody addPlayer, getPlayers do obiektu GameBoard:

public void addPlayer(Player player) {
    this.players.add(player);
    // Tu ew. możesz wykonać dodatkowe metody na graczu. np. zmienić jego kolor czy coś w zależności od przydzielonego mu miejsca na planszy
}

public List<Player> getPlayers() {
    return this.players;
}

A to z poziomu metody rozgrywającej grę. Dla tego przykładu powiedzmy że to będzie metoda main

public static void main(String[] args) {
    GameBoard  board = new GameBoard();
    Cube cube = new Cube();
    Player pl1 = new Player();
    Player pl2 = new Player();
    board.addPlayer(pl1);
    board.addPlayer(pl2);
    // Główna pętla gry
    while(true) {
        for(Player p : board.getPlayers()) {
            // Ruszasz gracza o wylosowaną liczbę oczek
            p.move(cube.getFiledsToMove());
        }
        // Pod koniec tury, sprawdzasz czy przypadkiem ktoś nie wyszedł po za planszę
        if(game.isGameEnded()) {
            // Jeżeli tak, przerywasz loopa z grą
            break;
        }
    }
    // Tutaj możesz wykonać jakieś dodatkowe metody np. wyrzucić graczy z gry, czy co tam potrzebujesz
}
0

Dzięki :) udało mi się zmodyfikować kod tak że teraz aktualna pozycja na planszy jest aktualizowana. A warunek żeby ruch nie przekroczył 40, tzn. kiedy jestem na 38 polu i wyrzucę 5 to wartość zwracanego pola powinna być 4 ( START to pole z numerem 1, można dla ułatwienia zmienić na 0 wtedy powinno być 3), wstawić w funkcji "main" czy w klasie player?

0

zrób to w metodzie move na zasadzie takiej:

public void move(int fields) {
    this.fieldNumber += fields;
    this.fieldNumber %= this.gameBoard.getMaxFieldNumber();
}

Tylko wtedy musisz odpowiednio zmodyfikować główną pętle bo metoda isGameEnded nigdy nie zwróci Ci prawdy. Do tego musisz do gracza za pomocą konstruktora przekazać obiekt GameBoard i przepisać zmienną z konstruktora do zmiennej wewnątrz obiektu

0

Inicjalizuje powoli plansze. Kolejne państwa dodaje w taki sposób

PolePanstwa[] nation = new PolePanstwa[3];
				nation[0] = new PolePanstwa("Neapol", 200,7); // nazwa, koszt zakupu, numer pola
				nation[1] = new PolePanstwa("Mediolan", 200,9);
				nation[2] = new PolePanstwa("Rzym", 240,10);

Czy można taką inicjalizację uruchomić w innej funkcji żeby nie zaśmiecać głównego kodu?

potem używam takiej petli, która sprawdza na którym polu się znajduję.

	for ( PolePanstwa p: nation)
			            		{
			            			if( pole == p.getNumber())
			            				System.out.println(" Jesteś w " + p.getName());
			            		}
0

Można. Initializujesz tablicę w głównej metodzie, a następnie przekazujesz ją do metody:

PolePanstwa[] nation = new PolePanstwa[3];
metoda(nation);

A tutaj ta metoda:

public void metoda(PolePanstwa[] nation) {
    nation[0] = new PolePanstwa("Neapol", 200,7); // nazwa, koszt zakupu, numer pola
    nation[1] = new PolePanstwa("Mediolan", 200,9);
    nation[2] = new PolePanstwa("Rzym", 240,10);
}
0

Tego mi było trzeba :) Napotkałem dziwny problem, otóż stan gotówki danego gracza obliczam na podobnej zasadzie co pole na którym się znajduje. Lecz jeśli państwo kosztuje np. 200$ to zamiast zmniejszyć stan konta o tą wartość, zastępuje ją.

OplataZaPanstwo = Gracz1.getMoney() - p.getPrice();   // stan konta - cena państwa
         			Gracz1.cash(OplataZaPanstwo);

A w klasie player mam taką metode

	public void cash(int hajs)
	{
		this.money = this.money - hajs;
	}

private int money = 1000;
	
0

To co w tej chwili robisz to Gracz1.getMoney() = 1000 - p.getPrice() = 200 co daje 800, a potem w Gracz1.cash(OplataZaPanstwo) robisz znowu this.money = 1000 - OplataZaPanstwo = 800 co Ci daje 200. Dlatego wartości się zastępują.
Prościej by było w klasie Player dodać np.: takie dwie metody

public void zwiekszKase(int money)
{
    this.money = this.money + money;
}

public void zmniejszKase(int money)
{
    this.money = this.money - money;
}

// albo jedną 
// i w niej w zależności od tego czy wyślesz wartość ujemną czy dodatnią, to wartość this.money zostanie zmniejszona lub zwiększona.
public void zmienKase(int money)
{
    this.money = this.money + money;
}

wtedy w Twoim przypadku robisz już tylko:

Gracz1.zmniejszKase(p.getPrice());
//albo
Gracz1.zmienKase( - p.getPrice());

zamiast tego:

OplataZaPanstwo = Gracz1.getMoney() - p.getPrice();   // stan konta - cena państwa
Gracz1.cash(OplataZaPanstwo);

1 użytkowników online, w tym zalogowanych: 0, gości: 1