Creating Dice game in java using Multithreading [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I want to provide implementation of a 4 player dice game in which each player is implemented as a thread . Each player get a chance to throw the dice in order of player number . each throw dies return a number 1 to 6 only . the game stop whenever any player scores 25 point or more print winner player .
I am Thinking of creating classes
Dice for handling Dice
Board For handling all Thread and Player Score
TheGame for Starting game
My class Dice
import java.util.Random;
public class Dice {
Random dice;
public Dice()
{
dice=new Random();
}
public int throwDice()
{
int a= dice.nextInt(70);
a=a/10;
if (a==0)
return 1;
else return a;
}
}
My Player Class
public class Player extends Thread {
Board board;
int num;
public Player(Board b,int n)
{
board=b;
num=n;
}
public void run()
{
System.out.println("Player "+num+" is started, playing game...");
while(board.flag)
{
board.play(num);
}
}
}
Game Class
public class TheGame {
public static void main(String[] args) {
System.out.println("Initializing board...");
Board b=new Board(); //Creating object of class board
System.out.println("Initializing players...");
Player p1=new Player(b,1); // Every player is Thread
Player p2=new Player(b,2);
Player p3=new Player(b,3);
Player p4=new Player(b,4);
p1.start(); //Starting Thread
p3.start();
p2.start();
p4.start();
}
}
I am not able to think Logic or decide where to start in class Board.
Please Help me with Board code
This is not assignment or homework .
I want to do it by myself but don't have any deep idea about Synchronization in Threading
I am trying to code i am not asking complete tutorials i am just asking how do i set order when player 1(thread) get execute after player 1 have done his chance.

This is just to point you in the right direction. You need to read a lot more than I can ever write here. Then you need to to fix all manner of weird and irreproducable bugs. But you did ask...
I think it's a lot simpler, and more interesting, if all 4 players throw at once. (Though you might have more than one winner.) To do that:
Create global monitors and field (Perhaps in Game class):
public static final turnMonitor = new Object();
public static final controlMonitor = new Object();
public static volatile gameOn = true;
Then create a Player class with a run method. (Player can extend Thread, or it can extend Runnable and you can pass it to a new Thread.) Like so:
public void run() {
while (gameOn) {
synchronized (turnMonitor) { turnMonitor.wait(); }
...roll dice here...
...Put sum of Player rolls in volatile instance field or synched field...
...Update volatile player turn counter...
synchronized (controlMonitor) {
// Tell control monitor we're done.
controlMonitor.notifyAll();
}
}
}
Then you'll want control code (in the Game class?):
while (true) {
// Roll dice
synchronized (turnMonitor) { turnMonitor.notifyAll(); }
// Wait for dice to roll
do {
synchronized (controlMonitor) { controlMonitor.wait(); }
} while ( ...not all players have rolled this turn... );
if ( there's a winner ) break;
}
gameOn = false;
This should give you a start. Do study up on synchronization, volatiles, wait(), and notifyAll(). If you can't find good examples anywhere, check here (for the very basics).
When starting, print lots of debugging messages. Threads are always running when you're not expecting them to. You are going to be surprised.
To have the players roll one at a time, I think you'd want multiple turn monitors. You can notify only one waiting thread at a time, but you can't control which thread gets notified, so trying get the right thread off one monitor would be difficult.

Related

Java: trouble understanding recursive method calling

I made an 'Oregon Trail' like game, it uses a 'game over' method to ask if the user wants to play again.
The main issue:
My teacher mentioned something vague about if the game looped enough times, we'd end up with a stackOverflow. That makes sense to me because the game continues to nest methods inside of each other the way I have it, adding to the stack each time a 'new game' method is called because the outer methods are still there waiting to complete.
I've boiled down an example of what I mean. Assuming there were pauses for user input and such, how am I supposed to make sure my memory utilization doesn't keep growing as I call methods inside other methods? I think the word for this is 'recursive', thus my title.
If anyone could recommend correct form for dealing with this, I'd be really grateful.
public class Testing
{
public static void main(String[] args) {
System.out.println("main method");
gameStart();
}
private static void gameStart()
{
System.out.println("some other method called");
gameOver();
}
private static void gameOver()
{
System.out.println("game over called"); //I would ask the user if they want to play again.
//keeping it concise to illustrate my point, instead of using an if statement
gameStart();//starting the cycle I'm concerned about. Assume the user indicated they would like to play again.
}
}
Recursion needs a condition where it will not continue calling.
Recursion is most commonly seen where a method calls itself, such as computing the fibonacci sequence, where
fib(n) == fib(n-1) + fib(n-2)
fib(0) is defined as 0, so you don't have to compute.
fib(1) is defined as 1, so you don't have to compute.
Every other number is computed by the fib() method calling itself twice, but it escapes making the recursive call for the two defined cases, where there is nothing to compute. In pseudo code
int fib(int n)
{
if (n == 0) return 0; // doesnt have to recursively call
if (n == 1) return 1; // same
return fib(n-1) + fib(n-2);
}
In your case, you have two methods that call each other, but you have no condition where the calls can escape from that.
A possibility would be that gameOver() only calls gameStart() when the game ends in a tie, something like
public class Testing
{
public static void main(String[] args) {
System.out.println("main method");
gameStart();
}
private static void gameStart()
{
System.out.println("some other method called");
gameOver();
}
private static void gameOver()
{
System.out.println("game over called");
if (gameTied()) {
gameStart();
}
}
}
If you're just asking "do you want to play again?" -- that would be better done in main, along the lines of
public static void main(String[] args) {
System.out.println("main method");
String playGame = "Yes";
while (playGame.equalsIgnoreCase("Yes") {
gameStart();
playGame = ask("Play again?");
}
}
To avoid unlimited recursion you may switch over to iteration and introduce return values for those methods which currently decide how to proceed (currently by directly calling the corresponding actions).
Let those methods return some sign what to do next, for example by using an enum.
Then write a loop which calls the right methods depending on the return values.
Example (abbreviated, I assume you know Java syntax):
enum Action { Start, ShowEnd, Quit }
main:
Action nextAction = Action.Start;
while (action != Action.Quit)
{
switch (action)
{
case Start:
nextAction = gameStart();
break;
case ShowEnd:
nextAction = gameEnd();
break;
// ToDo: write more actions!
default:
break;
}
}
This assumes that each such method executes until a decision was made about which action to take next.
This way your call stack will always be quite flat, as the execution always returns to the main method and then branches off into other methods.
When you write recursive code you should make sure that you have some sort of end condition BESIDES calling the function again. For example I added an end condition for the gameOver method with if(gamePlayedThisManyTimes <= 1) return;. When running the following code, the value you give the method gameStart will determine how many games you play and gameOver will decrement the value when it calls 'gameStart' to eventually reach that end condition of the recursion.
public static void main(String[] args)
{
System.out.println("main method");
gameStart(10);
}
private static void gameStart(int playGameThisManyTimes)
{
System.out.println("Game " + playGameThisManyTimes + " started...");
System.out.println("some other method called");
gameOver(playGameThisManyTimes);
}
private static void gameOver(int gamePlayedThisManyTimes)
{
System.out.println("game over called for " + gamePlayedThisManyTimes); //I would ask the user if they want to play again.
if(gamePlayedThisManyTimes <= 1)
return;
else
gameStart(gamePlayedThisManyTimes - 1);
}
Output
main method
Game 10 started...
some other method called
game over called for 10
Game 9 started...
some other method called
game over called for 9
Game 8 started...
some other method called
game over called for 8
Game 7 started...
some other method called
game over called for 7
Game 6 started...
some other method called
game over called for 6
Game 5 started...
some other method called
game over called for 5
Game 4 started...
some other method called
game over called for 4
Game 3 started...
some other method called
game over called for 3
Game 2 started...
some other method called
game over called for 2
Game 1 started...
some other method called
game over called for 1

Why is the inventory updating?

I am using Bukkit API 1.8 with Java 7.
I have a repeating task that loops through all the players on the server and sets their armor randomly to either leather, chainmail, etc...
When I use the method setHelmet,setChestplate, etc... I update their inventory like usual, but since this task is running every 6 ticks, it runs fast. Therefore, when a player tries to fire a bow, the bow resets its power every time this task runs.
Since I knew it was a problem with updating the inventory, I tried removing the updateInventory method.
After doing this the armor still got put on and changed, but the bow was still being reset every time the task was ran.
How would I keep the bow from resetting while still keeping the task running?
My code:
#SuppressWarnings("deprecation")
public static void repeatEffect()
{
main.getServer().getScheduler().scheduleAsyncRepeatingTask(main, new Runnable()
{
#Override
public void run()
{
for(Player o : Bukkit.getOnlinePlayers())
{
Material M1 = Material.WOOL;
int num = rainbow.get(o.getName());
if(num==1)
{
M1 = Material.LEATHER_HELMET;
}
else if(num==2)
{
M1 = Material.CHAINMAIL_HELMET;
}
else if(num==3)
{
M1 = Material.GOLD_HELMET;
}
else if(num==4)
{
M1 = Material.IRON_HELMET;
}
else if(num==5)
{
M1 = Material.DIAMOND_HELMET;
}
rainbow.put(o.getName(), num+1);
if(rainbow.get(o.getName())>5)
{
rainbow.put(o.getName(), 1);
}
ItemStack rrhelm = createItemStack(M1, 1, "§a§lR§b§la§c§li§d§ln§e§lb§f§lo§a§lw §c§lH§d§le§e§ll§f§lm§a§le§b§lt", "§7Very special piece of armor");
o.getInventory().setHelmet(rrhelm);
}
}
}
, 6, 6);
}
If changing armour resets the players bow, you could work around it by only changing the armour of players who are joining, not wielding a bow or just after an EntityShootBowEvent.
To see if the player is wielding a bow, use:
org.bukkit.Bukkit.entity.Player player = ...;
boolean hasBowEquiped = player.getEquipment().getItemInHand().getData().getItemType().equals(Material.BOW);
After testing this some more, the only way I was able to reproduce the bow complication was by calling the deprecated updateInventory() method which you said you removed. I'm fairly certain that you still have this method somewhere in your code because I can't find anything else that would cause the bow to act this way (I was still able to fire the bow but the animation looks glitchy and the power of the arrow is sometimes incorrect).
The only difference between my code is that I used new ItemStack(M1) instead of your createItemStack() method to instantiate the helmet (also tried changing name, lore and amount). I was still able to shoot a bow just fine. Could the resetting of the bow/inventory have something to do with your createItemStack method?
There's no reason why you should be running this task asynchronously. You're accessing the Bukkit API from an asynchronous task or different thread which is a big no-no and can cause all kinds of tricky problems. Use the scheduleSyncRepeatingTask method to run the task in the same thread.
For simplicity's sake I randomly set a single armor slot (also tried all four) to either leather or iron every 6 ticks. Didn't seem to interfere with the bow. Could we see your code? Here is mine:
public void onEnable() {
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
public void run() {
for (World world : Bukkit.getWorlds()) {
for (Player player : world.getPlayers()) {
if (Math.random() < 0.5) {
player.getInventory().setBoots(new ItemStack(Material.IRON_BOOTS));
} else {
player.getInventory().setBoots(new ItemStack(Material.LEATHER_BOOTS));
}
}
}
}
}, 0, 6);
}

Notifications in elevator simulator in Java

I am trying to implement an elevator simulator with Person and Elevator threads that share data in an ElevatorController class. My general implementation is that I have each Person store a controller variable, and from there, they request a ride in the elevator(current floor to some other floor). The controller keeps track of the requests, and the Elevator threads ask the controller for a new assignment(which floors to stop at and direction), which it generates based on the requests. The part I am having trouble with is the notification that the doors are open on a floor. I have tried putting a boolean array in the ElevatorController and have the Person threads call wait() (within a synchronized block on controller.areDoorsOpen) and then calling notifyAll on the areDoorsOpen array from the controller but I keep getting IllegalMonitorStateExceptions. My idea was that when the Person threads are notified (controller does so when it changes an entry in the areDoorsOpen array), they check the boolean array to see if the door is open on their floor (or if they are in the elevator, on their destination floor) and enter (or exit) the elevator or continue waiting. My question is why am I getting this exception on the wait() call in the person runnable.
Edit: The relevant code is
In the person Runnable,
private void waitForElevator() {
synchronized (controller.areDoorsOpenOn) {
System.out.printf("Person %d is waiting on floor %d to go to floor %d.\n", ID, currentFloor, destinationFloor);
while(!controller.areDoorsOpenOn[currentFloor]) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
In the controller class,
public boolean[] areDoorsOpenOn = new boolean[numberOfFloors];
public void notifyOpenDoors(int floor) {
synchronized (areDoorsOpenOn) {
areDoorsOpenOn[floor] = true;
notifyAll();
}
}
public void notifyClosedDoors(int floor) {
synchronized (areDoorsOpenOn) {
areDoorsOpenOn[floor] = false;
notifyAll();
}
}
The Elevator threads call notifyOpenDoors if they are on a floor that is in their assignment (stored as an array of integers) and then sleep for 3 seconds and call notifyClosedDoors
Thank you in advance for your help and let me know if you need any further clarification.
The stack trace from the IllegalMonitorStateExceptions will tell you where that's coming from - an important clue.
I believe you need to rethink which objects you are calling wait() and notifyAll() on. For example, you may want to always use areDoorsOpenOn.notifyAll() and areDoorsOpenOn.wait(). Currently, you're calling wait on the Runnable, and notifyAll on the Controllers.

Execute method from a different thread than the one it's called from

I am working on a game using the thread-per-client model. The game operates so that every half a second all of the players need to be updated. The updates all have to happen within the half a second interval, so they need to all be executed at the same time. My idea is to have a class that keeps track of when the "global update" needs to happen and then when the time comes, go through all of the players and tell it to update:
for(Player p : currentPlayers) {
p.update();
}
The problem is that since every player has their own thread, I want the player to take advantage of that fact since it is already there. If I go through the updates from a different class, then there is one thread executing what a couple hundred threads could be doing individually. How can I design it so that if a thread calls method 'update()' in class Player, a different thread than the one that called it executes it, or perhaps a different approach that can achieve the same goal?
If you need any clarification, please ask! Thanks a lot!
UPDATE: What do you guys think of this (I can't figure out how to format long amounts of code in posts!):
UPDATE 2: Just realized I would need to know when all of the players finish updating to reset the last time...
public class PseudoExample implements Runnable
{
// Assume 'players' is full of active players.
private Player[] players = new Player[100];
private long lastUpdate = System.currentTimeMillis();
public void run()
{
while (true)
{
if (System.currentTimeMillis() - lastUpdate >= 500)
{
for (Player p : players)
{
p.update = true;
}
}
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
}
}
}
private class Player implements Runnable
{
private boolean update = false;
public void run()
{
while (true)
{
if (update)
{
// Do updating here ...
}
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
}
}
}
}
}
I think the best way to handle this would be instead of calling p.update(), you could send an asynchronous message to p. This would use the Handler functionality. This is probably the cleanest way, although I believe some (likely trivial) overhead will occur from the message passing.
So, in your ticking thread (i.e. the one that calls the global update), you would have a reference to a Handler object for each client thread. Then, you look would look like
for (Player p : currentPlayers) {
p.handler().sendMessage(); // this isn't exactly the syntax
}
and in your Player, you would have a PlayerHandler object that extends Handler and overrides handleMessage(Message).
EDIT: the comments on the question are good ones - don't use more threads than you need to. They might seem to be the "right" abstraction, but they introduce a ton of potentially tricky issues. If all of your computation needs to be done in between ticks, it might not matter whether it's done sequentially or not.

What is the most efficient way to run many things off different time intervals in Java 6

I am working on a side scroller GUI game in Java. I have many kinds of enemies whose AIs run off Swing timers. As I understand it, Swing timers are kind of resource intensive, yet I still want my enemies to move around at different intervals. Is there a more efficient way to run things than using a different Swing timer for each kind of enemy?
A better way to solve this problems is to keep a list of enemies that exist on the screen, every time you render the next screen your main render loop should decided weather it should call any of the methods on the Enemy object or not.
public interface Enemy {
public void doNextThing();
}
public class TimedEnemy implements Enemy {
private long lastExecute;
private Enemy enemy;
private long threshHold;
public TimedEnemy(Enemy enemy, long threshold)
{
this.lastExecute = System.currentTimeMills();
this.enemy = enemy;
this.threshold = threshold;
}
public void doNextThing()
{
long duration = System.currentTimeMills() - lastExecute;
if( duration >= threshold) {
lastExecute = System.currentTimeMills();
this.enemy.doNextThing();
}
}
}
// main Render Loop
List<Enemy> enemies = new ArrayList<Enemy>();
TimedEnemy easy = new TimedEnemy(new EasyEnemy(),1000);
TimedEnemy hard = new TimeEnemy(new HardBadGuyEnemy(),100);
TimedEnemy boss = new TimeEnemy(new VeryBadBossEnemy(),50);
enemies.add(easy);
enemies.add(hard);
enemies.add(boss);
for( Enemy enemy : enemies) {
enemy.doNextThing():
}
If you really need to have every enemy AI run on its own thread then you need to use a TaskExecutor features of Java 5, with the Futures concept. Although running each AI on separate threads means that you have to be careful with thread synchronization.
You could use a regular timer http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html

Categories