Dynamic Programing to solve subset of given sum - java

Given the following Input
10 4 3 5 5 7
Where
10 = Total Score
4 = 4 players
3 = Score by player 1
5 = Score by player 2
5 = Score by player 3
7 = Score by player 4
Output should print the index of players who's score equal to 10. So for given above output it should print 1 4 or 2 3 because player 1 + player 4 score adds up to 10 and so does the scores by player 2 and player 3. I do not need to PRINT BOTH or ALL combinations. I just want to print any one combination that works.
For INPUT : 8 3 2 2 4 OUPUT : 1 2 3 since scores of player 1 player 2 and player 3 equal the total score of 8
So i have been reading Dynamic programing tutorials and videos for past week and also got help on stack overflow to fix my initial code.
Following is what i have so far
public boolean findSolution(int[] scores, int total) {
int W = total;
int players = scores.length;
boolean[][] myArray = new boolean[players + 1][total + 1];
for (int player = 0; player <= players; player++) {
myArray[player][0] = true;
}
for (int score = 1; score < total; score++) {
myArray[0][score] = false;
}
for (int player = 1; player <= players; player++) {
for (int score = 1; score <= total; score++) {
myArray[player][score] = myArray[player - 1][score];
if (score >= scores[player - 1]) {
myArray[player][score] = myArray[player - 1][score
- scores[player - 1]]
|| myArray[player][score];
}
}
}
return myArray[players][W];
}
This logic creates 2d array and does exhaustive search to see if the combination for a given total is possible and will return true if it is and false if it is not. Now i am having trouble printing the indexes of the players that make it true. So would highly appreciate if someone can help me print the index of a set of players who's score equals the total. I dont NEED TO PRINT all combinations.
Also please ask any question if you don't understand as i am not native English speaker.

Ok, so after you have created and updated boolean array myArray.
We will iterate from the last player to the first player, checking if we can use the current player in our final result
int currentScore = total;//Maintain the current score.
for(int i = lastPlayer ; i >= 0; i--){
}
Inside the for loop, to check if this current i player is belong to our final set of player, we need to check if there exists a solution for currentScore - score of i player
if (currentScore >= scores[i] && (i == 0 || myArray[i - 1][currentScore - scores[i]]) {
//Update current score
currentScore -= scores[i];
//Print name of the player.
System.out.println("Player " + i);
}

Related

A dice game between two players. The player who gets 21 first wins [closed]

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 4 years ago.
Improve this question
There is a game between two players, and the first player who gets 21 points wins.
when both players reach 21 on the same number of rolls, there is a tie.
The points are added up as the dices are rolled.
The format of this should be done as follows.
* GAME 1 *
Roll Player 1 Player 2
1 5 4
2 7 10
3 12 14
4 13 16
5 19 21
player 2 wins!
The code below is what I've tried so far.
I'm stuck because I have no idea how to create a chart like the one above.
If I try to make the chart inside the while loop, it will repeatedly make the chart.
If I try to make the chart outside the while loop, which is after the while loop, it will
execute only when one of the players reach points 21.
Can anyone help me out how to make this code?
import java.util.*;
public class Dice {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Random rand = new Random();
System.out.println("How many games do you want to play?");
int games= input.nextInt();
System.out.println(" *** Game 1 *** ");
int sum1=0;
int sum2=0;
while (sum1!=21&&sum2!=21){
int roll1 = rand.nextInt(6) + 1;
int roll2 = rand.nextInt(6) + 1;
sum1=+roll1;
sum2=+roll2;
}
if(sum1>sum2){
System.out.println("player 1 wins");
}
else if(sum1<sum2){
System.out.println("player 2 wins");
}
}
}
A few problem
you want to test that sum1 and sum2 are less than 21 not !=
you should use += not =+
Introduced a counter for the rolls
Note
I think you logic is not correct, though as what should happen if both get to 21 on the same throw?
System.out.println(" *** Game 1 *** ");
int sum1=0;
int sum2=0;
int rollNumber = 1;
System.out.println("Roll\tPlayer 1\tPlayer 2");
while (sum1 < 21 && sum2 < 21){
int roll1 = rand.nextInt(6) + 1;
int roll2 = rand.nextInt(6) + 1;
sum1 += roll1;
sum2 += roll2;
if (sum1 > 21) sum1 = 21;
if (sum2 > 21) sum2 = 21;
System.out.format("%d\t%d\t%d%n", rollNumber++, sum1, sum2);
}
if(sum1>sum2){
System.out.println("player 1 wins");
}
else if(sum1<sum2){
System.out.println("player 2 wins");
}
}
output
*** Game 1 ***
Roll Player 1 Player 2
1 5 4
2 4 5
3 2 3
4 3 1
5 3 3
6 2 3
7 5 6
player 2 wins
If you want a printout each turn, you need to print inside the while loop. Here would be an example snippet that has such a feature. Of course, this isn't a complete program, and could use some formatting love.
int sum1 = 0;
int sum2 = 0;
int round = 1;
while(sum1 < 21 && sum2 < 21) { // not sure if you noticed this bug in your code..
sum1 += rand.nextInt(6) + 1;
sum2 += rand.nextInt(6) + 1;
System.out.println("Round " + round + " " + sum1 + " " + sum2);
round++;
}

Creating a lottery draw method

Hello.
I'm working on a lottery system in a game that I'm working on.
My goal is to get a player randomly based on their amount input and the total value of the lottery pot at the moment of the drawing. E.G Pot is 100k, Player1 has put in 10k, and Player2 has put in 20k, meaning Player 1 has 1/10 chance of winning and Player2 has a 2/10 chance of winning.
totalPot, this is the total value of the pot
randomNR, this is a random number generation
userInput, this is the total input that the user has put into the lottery.
player, this is the player who inputted the amount above
I have already tried this:
public static void drawLottery() {
int totalPot = lotteryPot - 250;
int randomNR = Misc.randomInt(0, lotteryPot);
List<Player> keys = new ArrayList<Player>(lotteryEntries.keySet());
Collections.shuffle(keys);
for(int i = 0; i < totalPot;) {
for (Player o : keys) {
i += lotteryEntries.get(o);
if (i >= randomNR) {
System.out.println("Winner: " + o.getUsername() + " -> Random number: " + randomNR);
}
break;
}
break;
}
}
But that just caused the same player to be drawn over and over again.
I don't know what to do and help would be greatly appreciated.
You can iterate over all the lottery entries and keep a cumulative total. The first time the cumulative total exceeds the winning number is the player that has won.
For example:
Player 1: 20
Player 2: 30
Player 3: 50
Player 4: 10
The winning number is chosen to be 51. The cumulative total starts at 20. This is not greater than 51, so player 1 has not won. Then we increment to 50. Not greater than 51, player 2 has not won. Then we increment to 100 which greater than 51 so player 3 has won.
public static Player getWinner(int winningNumber, Map<Player, Integer> lotteryEntries)
{
int cumulativeProbability = 0;
for (Map.Entry<Player, Integer> entry : lotteryEntries.entrySet())
{
cumulativeProbability += entry.getValue();
if (cumulativeProbability >= winningNumber)
{
return entry.getKey();
}
}
throw new RuntimeException("Winning number not within total pot size");
}
Use the pot to ponderate your random choice. Pick a number inside the pot. define a range in the pot for every player. If the picked number is in the range, this player is the winner.
For example, the pot is 30. Player 1 put 10 and player 2 put 20. You pick a random number between 0 and 30. Let's say random gives us 23. The range corresponding to player 1 is 0 to 10 and the range corresponding to player 2 is 10 to 30. Then player 2 has won.
This should look like this :
//pick a random number inside the pot
Random rand = new Random();
int randNum = rand.nextInt(totalPot);
//Define the pot range corresponding to a player
int rangeStart = 0;
int rangeEnd = 0;
//go through all enties (all players)
for(Entry entry : lotteryEntries.entries()) {
//Define the range corresponding to this player
value = entry.getValue()
rangeStart = rangeEnd;
rangeEnd += value;
//If the picked random num is in the range, this player is the winner
if( randNum >= rangeStart && randNum < rangeEnd) {
System.out.println("Winner: " + entry.getKey().getUsername()):
System.out.println("randNum: " + randNum);
break;
}
}

Locking user input and counting amount of time loop happens

I'm new to this so sorry if I am a bit confusing
So this is my code, its a game based around 2 players adding 1 or 2 to the variable "counter" the one who puts the final 1 or 2 adding all the numbers up to 21 wins.
So what I would like to have help with is that I want to lock the user input to only be able to select 1 or 2, not anything else because that would break the rules of the game. Also I would like to have a way to determine who won, player 1 or player 2. Like counting the amount of times the loop happens, so I can distinguish if player 1 or 2 one.
Any help would be appreciated! Thanks!
package hemtenta;
import java.util.Scanner;
public class Hemtenta {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 0;
int addcounter = 0;
int sum;
System.out.println("Welcome to 21");
System.out.println("The game revolves about you or your opponent getting to 21 ");
System.out.println("You both start on the same number 0, ");
System.out.println("adding 1 or 2 to see which one of you will put the final number adding it all up to 21 and winning.");
System.out.println("Think smart!");
while(counter <= 20) {
System.out.println("Please choose to add 1 or 2");
addcounter = input.nextInt();
counter += addcounter;
System.out.println("We are now on a total of " + (counter));
}
if (counter==21) {
System.out.println("Congratulations x! you won");
}
else {
System.out.println("Something went wrong! Try again");
}
}
}
You could look towards adding a
while (addcounter != 1 && addcounter != 2) {
// Prompt for values
}
To check that the value input by the user is either a 1 or a 2. If it isn't, then don't accept it and continue prompting till a valid input is registered.
And a
int turnCounter = 0;
...
// Within the loop
turnCounter += 1;
...
// At the end
if (turnCounter % 2 == 0) {
//Player Y wins
} else {
//Player X wins
}
To identify the turns, since turn 1s will be by player X, and turn 2s will be player Y. All turns by player Y will be in multiples of 2.

java - establishing new variables based on input

So, the program calls for a bowling game. Once you ask how many players, every player gets 2 throws to knock down 10 pins (simulated by random numbers). If you knock them all down with the first go, then you get 20 points, if on your second go you get 15 points, other than that score = throw 1 + throw 2.
The tricky part for me has been getting each player to alternate frames (2 throws = 1 frame, up to ten frames per player) while the program keeps track of everyone's score! I thought I had it with this but the randoms just add up ill post the output on the bottom
import java.util.Scanner;
public class Bowling {
public static void main(String [] args){
Scanner input = new Scanner (System.in);
Game aNew = new Game();
int player;
int i;
int j;
int nPlay;
System.out.print("How many players are there?: ");
nPlay = input.nextInt();
for (j = 1; j<= 10; j++) {
for (i = 1; i <= nPlay; i++ ){
player = i; // i tried player i = new Player() but get error "value
aNew.getScore(player); // already used in scope""
}
}
Games class:
import java.lang.Math;
public class Game {
int score = 0;
int player;
int ran1;
int ran2;
public Game() {
}
public int getScore(int player){
ran1 = (int) (9 * Math.random());
ran2 = (int) (((10 - ran1)) * Math.random());
if (ran1 == 10){
score += 20;
} else if (ran1 + ran2 == 10){
score += 15;
} else {
score += ran1 + ran2;
} System.out.println("Player " + player + " score is: " + score + "\n");
System.out.println("ran1: " + ran1 + " ran2: " + ran2);
return score;
}
}
Player class:
public class Player {
/** this class is not doing anything, however i would like for an object to store a score for every player to keep track if that is possible?*/
int score;
public Player (){
int score;
}
}
Output: (suspicious how every time the last player had the highest or I would have never noticed it didn't work!)
How many players are there?: 2
Player 1 score is: 2
ran1: 1 ran2: 1
Player 2 score is: 11
ran1: 8 ran2: 1
Player 1 score is: 16
ran1: 5 ran2: 0
Player 2 score is: 21
ran1: 4 ran2: 1
Player 1 score is: 29
ran1: 8 ran2: 0
Player 2 score is: 35
ran1: 5 ran2: 1
Player 1 score is: 40
ran1: 3 ran2: 2
Player 2 score is: 47
ran1: 6 ran2: 1
Player 1 score is: 56
ran1: 8 ran2: 1
Player 2 score is: 61
ran1: 5 ran2: 0
Player 1 score is: 68
ran1: 7 ran2: 0
Player 2 score is: 77
ran1: 8 ran2: 1
Player 1 score is: 85
ran1: 4 ran2: 4
Player 2 score is: 90
ran1: 4 ran2: 1
Player 1 score is: 97
ran1: 7 ran2: 0
Player 2 score is: 103
ran1: 3 ran2: 3
Player 1 score is: 107
ran1: 4 ran2: 0
Player 2 score is: 114
ran1: 3 ran2: 4
Player 1 score is: 121
ran1: 7 ran2: 0
Player 2 score is: 125
ran1: 0 ran2: 4
Your Player class is currently doing nothing. Fix this by first making accessors and modifiers for your Player.score variable like this. Maybe even give them a name:
public class Player {
int score;
String name;
public Player(String name) { this.name = name; }
public void getName() { return this.name; }
public void setScore(int newScore) { score = newScore; }
public int getScore() { return score; }
}
now your game class should have a collection type of players like
public class Game {
List<Player> players = new List<Player>();
public Game() {
}
public void AddPlayer(Player p) {
players.add(p);
}
public Player getPlayer(int index) { return players.get(index); }
public void playerBowl(Player p) {
ran1 = (int) (9 * Math.random());
ran2 = (int) (((10 - ran1)) * Math.random());
if (ran1 == 10){
p.setScore(p.getScore() +20);
} else if (ran1 + ran2 == 10){
p.setScore(p.getScore() +15);
} else {
p.setScore(p.getScore() + ran1 + ran2);
} System.out.println("Player " + p.getName() + " score is: " + p.getScore() + "\n");
System.out.println("ran1: " + ran1 + " ran2: " + ran2);
}
}
Ill leave the main for you to figure out :D. Sorry if the syntax is a little off, I wrote it in the edit window :/
Seems to me that your troubles start here:
player = i; // i tried player i = new Player() but get error "value
aNew.getScore(player); // already used in scope""
The correct way would be:
Player i = new Player(); //mind the capital!
For the rest: You would probably want to use a List of Players and initialize this list once you know how many players there are. Finally, the getScore function should not modify the score variable in the Game class, but rather the score variable of a Player (with player.score = 20). You need to know your players in your Game class, but you can do this in several ways: pass a player as an argument to getScore, or pass the whole list of players at an earlier point.
All in all, there is quite a bit of code to rewrite for you, but I'm sure playing with this code will be very educational.

Java Netbeans 6.5 Mastermind Calculating White Pegs

For my Mastermind Game I am using 6 numbers instead of 6 colours. Also instead of showing black and white pegs, just 2 sentences are outputted. One reads:
"The number of correct digits in the right position is __ "(black pegs/bothRight)
"The number of correct digits in the wrong position is __ "(white pegs/numberRight)
For the 4 digit guesses that are submitted, I am using an array called guessArr, which accepts 4 values from 4 input boxes.
guess0 = Integer.parseInt(firstInput.getText());
guess1 = Integer.parseInt(secondInput.getText());
guess2 = Integer.parseInt(thirdInput.getText());
guess3 = Integer.parseInt(fourthInput.getText());
//New array to arrange guesses
int[] guessArr = new int[] {guess0,guess1,guess2,guess3};
For the answer generated by the computer,
//Create a 4 digit code made of random numbers between 1 and 6
answerArr[0]=(int)(Math.random()*6+1);
answerArr[1]=(int)(Math.random()*6+1);
answerArr[2]=(int)(Math.random()*6+1);
answerArr[3]=(int)(Math.random()*6+1);
Finding the amount of black pegs is easy:
//Calculate number of correct digits in correct position
for (int i = 0; i < 4; ++i)
{
if (answerArr[i] == guessArr[i])
{
used[i] = true;
bothRight++;
}
}
EDIT
I've Solved It!
// Calculate number of correct numbers in wrong position
//Declare variables for what digits are in the answer
Integer digit1 = 0, digit2 = 0, digit3 = 0, digit4 = 0, digit5 = 0 , digit6 = 0;
//Find what the answer digits are
for (int k = 0; k < answerArr.length; ++k){
if (answerArr [k] == 1)
{
digit1++;
}
if (answerArr [k] == 2)
{
digit2++;
}
if (answerArr [k] == 3)
{
digit3++;
}
if (answerArr [k] == 4)
{
digit4++;
}
if (answerArr [k] == 5)
{
digit5++;
}
if (answerArr [k] == 6)
{
digit6++;
}
}
//Declare variables for what digits are in the answer
Integer gDigit1 = 0, gDigit2 = 0, gDigit3 = 0, gDigit4 = 0, gDigit5 = 0 , gDigit6 = 0;
//Find the guess numbers submitted
for (int p = 0; p < guessArr.length; ++p){
if (guessArr [p] == 1)
{
gDigit1++;
}
else if (guessArr [p] == 2)
{
gDigit2++;
}
else if (guessArr [p] == 3)
{
gDigit3++;
}
else if (guessArr [p] == 4)
{
gDigit4++;
}
else if (guessArr [p] == 5)
{
gDigit5++;
}
else if (guessArr [p] == 6)
{
gDigit6++;
if (gDigit6 == 0)
{
gDigit6++;
}
}
//Find the value of correct numbers submitted in the guess
Integer correctNumbers = Math.min (digit1, gDigit1) + Math.min (digit2, gDigit2) + Math.min (digit3, gDigit3) +
Math.min (digit4, gDigit4) + Math.min (digit5, gDigit5) + Math.min (digit6, gDigit6);
//Calculate value of numberRight
numberRight = (correctNumbers - bothRight);
}
Any help would be greatly appreciated. :D Thanks.
First, I'll say up front, I'm not going to give you any code since this is either a learning exercise, so you can learn the language, or else this is a class problem.
So, lets think about this logically... One way you can you can solve this is by counting the number of a type of colors.
As an example, suppose the player guessed 2 blues, and 2 greens, and the answer has 1 blue, 1 red, and two greens.
The player guessed 3 of the right colors, so you would give them 3 white pegs UNLESS they got some in the right spot. Now, suppose that they got one of those blues in the right spot, that means they have 1 black peg, which replaces a white peg. So, the grand total is 2 white pegs, and 1 black peg.
So, to find the number of "Correct Colors" you should check each color (good chance for a loop?) and compare the number of each color that the player guessed, to the number of each color that the solution has.
Put another way, you don't want to compare the guess to the answer. You want to compare the count for each color on the guess, to the count of each color on the solution.
Then, you get "White pegs" by this pesudo-code:
int whitePegs=correctColors-blackPegs;
Edit 1: Comparing answers one color at a time
If you're going to hold the count for each color, then you're going to want to use two arrays, one for the guess, and one for the solution. Each element in the array will hold the count for the color, like this:
r=red, o=orange, y=yellow, etc.
R O Y G B
Guess: [0][2][1][1][0] (Total is 4, for 4 pegs
Actual: [1][1][2][0][0] (Total is 4) for 4 pegs
Matches:[0][1][1][0][0] (Total is 2) This is "correctColors" from above

Categories