# logic problem

Hi there,

I'm making a database-driven website for my local tennis club.  It enables users to track and update scores.  All the main logic is in place, but I've decided to factor in total wins and I've run into a bit of a snag with the code.

First, the rules of the house league.  There aren't many...First player to '8' wins, if the hour runs out and no one has reached '8', the person leading wins (of course).  That's about it.  Here's what I have so far.

First, a test set assuming everyone has played already :

Player 1 - 3  8  8
Player 2 - 8  2  1
Player 3 - 4  8  5
Player 4 - 4  8  8

Next, the code I came up with (it's in PHP)

``````      while(\$result = mysql_fetch_array(\$house))  {
foreach(\$result as \$key => \$value)  {
if(preg_match("/scr/", \$key))  {
// CREATE A SEPARATE ARRAY OF SCORES FOR EACH PLAYER
\${"scr_array" . \$count}[] = \$value;
}
}
\$count++;
}
for(\$i = 1; \$i <= \$member_count; \$i++)  {
// STORE THE SCORES IN A MULTIDIMENSIONAL ARRAY
\$multi_array[] = \${"scr_array" . \$i};
}
// THIS IS THE ALGORITHM IM HAVING TROUBLE WITH
\$total_wins = array();
for(\$i = 1; \$i <= count(\$multi_array); \$i++)  {
\$wins = 0;
// SUBTRACT 1 FROM ARRAY COUNT AS SOMEONE CANT PLAY THEMSELVES
for(\$j = 1; \$j <= count(\$multi_array) - 1; \$j++)  {
if(\$multi_array[\$i][\$j] >  \$multi_array[\$j][\$i])  {
\$total_wins[\$j] =  \$wins + 1;
}
}
}``````

Anyways,  I'm sure there's a more elegant way to do this but hey, i'm new to programming and this is what i've come up with.

Anyways, the results weren't what I was hoping for.  Player one should have 2 wins, Player two should have 1 win, Player 3 should have 1 win and Player 4 should have 2 wins.  The totals_wins array only has 1 win for Player one, 1 win for Player two and nothing for the last two players.  Please help!

Beverley Portlock

Arrays can be confusing. I would separate the logic associated with a player's score out into a separate class. That way each player's details are easily worked on

(UNTESTED)

``````class PlayerScore {

public \$name;
public \$scores;
private \$winsLimit;

function __construct( \$name, \$winsLimit ) {
\$this->name = \$name;
\$this->scores = array();
\$this->winsLimit = \$winsLimit;
}

\$this->scores [] = \$score;
}

// Count the number of wins
//
function getWins() {
\$count = 0;

foreach( \$this->scores as \$aScore )
if ( \$aScore >= \$this->winsLimit )
\$count++;

return \$count;
}
}``````

This way you can retrieve each player's details and theire scores and simply add them into an array as player objects

\$player = new PlayerScore("player1", 8 );

\$scoreArray [] = \$player;

Obviously filling this from a list of scores in MySQL would be something like

\$player = new PlayerScore( \$rw['playerName'], 8 );
while (\$rw = mysql_fetch_assoc( \$rs ) )

To determine how many wins a player had just use \$player->getWins() so you could run down the scoring array

foreach ( \$scoreArray as \$aPlayer )
if ( \$aPlayer->getWins() > 0 )
echo \$aPlayer->name . " has {\$aPlayer->getWins()} wins <br/>";

duder78

Hmm..haven't moved onto OOP yet.  Just got my feet wet with procedural stuff using PHP and MySQL.  I can see your logic working, but what about cases where time ran out and the neither of the two competing players reached 8?  You would still have to compare two scores to see which is greater and increment the wins.

Using the test set, could someone possibly show me how to do this without classes and such?  OOP is something i'm looking to learn, but with all the work i've done with this I don't want to introduce those concepts at this point.  All the logic is in place and working fine so I don't want to mess with it.

I think we might need to know a little more about your rules.  Is it always first player to 8, win by one?  What about handicaps (they are common in golf - not sure about club tennis)?  Are the contests part of a larger tournament or series?  What happens if the time runs out and both players have a 6 - how do you handle your ties?  Do victories get any weighting -- example, let's say you are really good and win your contest 8-0 in less than an hour.   Does that place you on equal footing with a couple of duds who battle for an hour and end in a scoreless tie?  Or who play for an hour and the score ends 4-3?

Ok the rules :

First player to 8 wins
if time expires, the player ahead wins (i.e 5 to 3 etc.)

Here is the test set i'm using :
``````PLAYER 1 - 3 8 8
PLAYER 2 - 8 2 1
PLAYER 3 - 4 8 5
PLAYER 4 - 4 8 8``````

Going by this, the wins should be as follows:
``````PLAYER 1 - [2 wins]
PLAYER 2 - [1 win]
PLAYER 3 - [1 win]
PLAYER 4 - [2 wins]``````

Hope this helps.  BTW, disgard the code I have...it's completely wrong.  Write it in whichever language is comfortable for yourselves.

I really need this to work!  Thanks in advance...

Oh yeah I forgot...no, you don't have to win by a certain margin.  As soon as someone hits 8 or if time runs out, it's over.

Damn, sorry again. Just to answer some of Ray's questions...

It's just a monthly house league, no larger scheme to all of this.  Everyone's scores are reset monthly.  Ties are allowed as well.  First to 8 wins,and  if you don't hit 8 but are leading when time expires, you win.  That's about it.
Hi duder

I'm not sure how you determine timeout.
I assumed array \$games. but the logic will be same even if you define timeout in different way.

Here is my code.

``````<?

\$games = array(
// score array is in order of player 1, player 2, etc.
array("timeout" => false, "scores" =>array ( 3, 8, 4, 4)),
array("timeout" => false, "scores" =>array ( 8, 2, 8, 8)),
array("timeout" => false, "scores" =>array ( 8, 1, 5, 8)),
array("timeout" => true,  "scores" =>array ( 5, 4, 3, 2))
);

\$games_count = count(\$games);
\$total_wins = array(0, 0, 0, 0);
\$member_count = count(\$total_wins);
\$timeout = false;

// for each game
for (\$i = 0; \$i < \$games_count; \$i++)
{
\$winning_score = 0;
\$timeout = \$games[\$i]["timeout"];

if (\$timeout)
{
// determine best score in the game
for(\$j = 0; \$j <= \$member_count; \$j++)  {
// check if the score is best.
if (\$winning_score < \$games[\$i]["scores"][\$j])
{
\$winning_score = \$games[\$i]["scores"][\$j];
}
}
}
else
{
\$winning_score = 8;
}

// check if player has winning score
for(\$j = 0; \$j <= \$member_count; \$j++)  {
if (\$games[\$i]["scores"][\$j] == \$winning_score)
{
\$total_wins[\$j] += 1;
}
}
}

// result
for (\$i = 0; \$i < \$member_count; \$i++)
{
// print PLAYER x - [y wins]
print("PLAYER ".(\$i+1)." - [". \$total_wins[\$i]. " win". (\$total_wins[\$i] > 1 ? "s": ""). "]<br>");
}
?>``````

Basic flow is like this.

In addition, you do can use max function to determine winning score instead of iterating all scores in array.

``````// determine best score in the game
\$winning_score = max(\$games[\$i]["scores"]);``````
Please go back and look at the snippets here: ID:34880713.  How could there be four players and six wins?  It looks like player 1 and player 4 both scored 8, but that would clearly be impossible in a win-by-one contest.  Can you clarify this, please?

Thank you for the responses.  I haven't looked closely at requeues answer yet, and sorry Ray, the scoring in my test set was in fact wrong.  Try this one out :

``````Player 1 - 8 8 8
Player 2 - 2 6 5
Player 3 - 3 8 1
Player 4 - 4 8 6``````

Wins should look like this :

``````Player 1 - [3 wins]
Player 2 - [0 wins]
Player 3 - [1 win]
Player 4 - [2 wins]``````

I double checked and there are no ties, in one case [Player 4] time runs out on a match and he wins 6 to 1.  Everyone plays each other once.  In this case there are 6 wins as well..not sure about the math on why there are 6 wins, but it is definitely possible.

requeues solution introduced a \$timeout variable.  I think things are getting a little more complicated than necessary.  I just need it to compare two scores, and iterate the wins for the player if it is greater than the other one.  Sure, 8 it a winning score, but I believe comparing everything anyways and not testing for 8 is the best way to go.  But what do I know :p

There are only 3 scores per player because you cannot play yourself...check out this link ( this is what the houseleague tracking sheets look like)

http://www.elgrantos.com/tennis/images/test_house.jpg

This is the link to the website i'm working on...you can't login but you can browse the houses if you like :

http://www.elgrantos.com/tennis
Please help clarify this -- I think maybe the matrix of four player and three columns of numbers is what is confusing.  How many players are engaged in a contest? Two, three or four?  It is easy to understand if you have something like this, where in all cases except the fourth, Player 1 is the winner.  Can you help us translate that into what we should understand about the four-player, three-column display?  Thanks.
``````Contest 1 - Victory by max-score mercy rule
Player 1 - 8
Player 2 - 7

Contest 2 - Victory by high-score when time expires
Player 1 - 2
Player 2 - 1

Contest 3 - Victory by default
Player 1 - shows up
Player 2 - defaults

Contest 4 - No decision, tied when time expires
Player 1 - 4
Player 2 - 4``````

So sorry.  It's apparent now that i've made alot of assumptions and haven't made myself completely clear.  Every match is always a 1 vs 1 match.  Every one plays everyone else in the house once.  That's why there are only 3 scoring fields for say, a house with 4 players.  You can't play yourself.  Ties are allowed, first to 8 wins OR the player leading after the hour is up wins. For your example with Contest 3...there are no defaults.  If someone doesn't show up, no scores are inputted and it's like no match was ever played between the two[0 - 0].   I think that's all the important stuff...
greetings, , I may not get what you mean by looking your code, please consider for your recording, you use some "tennis logic" as the recorder -
Player 3 - 3 8 1  - ONE WIN

Player 4 - 4 8 6  - TWO WINS

but there is NO computer logic in determining your wins, please consider a different way of recording for your computer (data set) -

Player 3 - 0 1 0  - ONE WIN

Player 4 - 0 1 1  - TWO WINS

you can display the first set (3 8 1) as your scores to the monthly results, and use the Win Logic record (0 1 0) to count the wins, if you are keeping a "TIE" score in there also

Player 3 - 0 2 1  - ONE WIN (2) - ONE TIE (1)

Player 4 - 0 2 2  - TWO WINS (2) - NO TIE

! To me, your data recording of - 3 8 1 - gives no direct indication of wins or ties without MORE DATA added to make distictions

Damn...I'm sort of sorry to hear that.  I can't really change the set of rules as they have been put in the place by the tennis club and have been used for some time.  I guess I could add a form field on the backend to enter total wins per player, per month but that could result in errors based on user input.

Thanks for helping anyways guys, it was worth a shot.
Not sure what you mean by the last post?  I did not see comments here that said anything about changing the rules? But I'm only half awake today. You said that yours is a "database-driven website", so to me it's not about changing any rules, is about how you enter and retrieve Data from your database. "You may can work around it" with a different method of database usage ? ? or not? However, if the only information you have, and the only information you can get is the Player data sets you have presented -

Player 4 - 4 8 6

then there is no way, I can see, to determine that the "6" is a "Win" for player 4 because of a timeout ending the game, or the "4" may or may not be a tie. . .  At the end of a match, the players know the result, as who won, a tie, a win by timeout, or a forfeit, , and has nothing to do with a computer or database. Whatever is done to the database entries does change the tennis play or rules, I don't think? So have each player enter the score as a number (4 - 5 - 8 etc.) and a checkbox or other, to check if it was a win, or another box (select) for more options (tie). As to "errors based on user input", If the players are giving you the entries (not an official keeping records), then there will be errors, but if it if displayed for all to see, then the errors will be noticed and corrected, I would guess?
Also, I looked at your  test_house.jpg  , so maybe you could add symbols to the house data entries?
6*    for a win from timeout
5=    for a Tie

I'm confused ;s  Changing the database wouldn't be fun, how about changing the arrays upon creation?  What if another number is introduced to the arrays to make each set have 4 values?  Something like the 'x' seen in the test_house.jpg image.  Perhaps make it a negative value so that it is apparent that the 'player would be playing themselves' so computations aren't done.

Something like this :

``````Player 1 : [-1] 8 8 8
Player 2 : 2 [-1] 6 5
Player 3 : 3 8 [-1] 1
Player 4 : 4 8 6 [-1]``````

Does that make more sense?  If you can't tell, i'm completely lost here.  I really thought I was onto something when I created that multi-dimensional array and looped through the values and tested them against each other...so much for THAT huh..
Member_2_248744

membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.