Solved

logic problem

Posted on 2011-02-12
20
286 Views
Last Modified: 2012-05-11
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;  
			}
		}
	}

Open in new window


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!

0
Comment
Question by:duder78
  • 11
  • 3
  • 3
  • +2
20 Comments
 
LVL 34

Expert Comment

by:Beverley Portlock
ID: 34880005
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;
     }


     function addScore( $score ) {
          $this->scores [] = $score;
     }


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

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

          return $count;
     }
}

Open in new window


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 );
$player->addScore( 3 );
$player->addScore( 8 );
$palyer->addScore( 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 ) )
     $player->addScore( $rw['score'] );


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/>";


0
 

Author Comment

by:duder78
ID: 34880037
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.  

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34880342
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?
0
 

Author Comment

by:duder78
ID: 34880713
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

Open in new window


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]

Open in new window


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...
0
 

Author Comment

by:duder78
ID: 34880728
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.
0
 

Author Comment

by:duder78
ID: 34880847
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.  
0
 
LVL 2

Expert Comment

by:requeue
ID: 34881337
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>");
}
?>

Open in new window


Basic flow is like this.
Flowchart
0
 
LVL 2

Expert Comment

by:requeue
ID: 34881470

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"]);

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34882768
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?
0
 

Author Comment

by:duder78
ID: 34883383
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

Open in new window


Wins should look like this :

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

Open in new window


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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:duder78
ID: 34883488
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
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34884112
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

Open in new window

0
 

Author Comment

by:duder78
ID: 34884787
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...
0
 
LVL 33

Expert Comment

by:Slick812
ID: 34885544
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

0
 

Author Comment

by:duder78
ID: 34890032
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.
0
 
LVL 33

Expert Comment

by:Slick812
ID: 34893351
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
0
 

Author Comment

by:duder78
ID: 34893790
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]

Open in new window


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..
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 500 total points
ID: 34894201
ok, your last post has begun to let me see some light, maybe?
You had mentioned about the time outs, as if that was a factor independent of the scores,
but now I think you were not talking about anything that influenced the score, only why the
winning score was not 8, so that clears some of my attempt to understand.
A multi-dimensional array might be used, and I have built some code for that.
I do not have your database, so I can not do the DB access, but the code below creates a $multi_array[ ] with the 'scores' holding the $value in your DB $key, $value pair.

I think this gives the correct values, let me know if this has any working as you need or not.
<?php

$member_count = 4;
$multi_array = array();
for ($i = 0; $i < $member_count; ++$i) $multi_array[$i] = array('wins' => 0, 'ties' => 0);

// the array 'scores' below would be populated from your foreach($result as $key => $value)
// in your database access from while($result = mysql_fetch_array($house))
$multi_array[0]['scores'] = array(0, 8, 8, 8);// $value for each play, 0 for that corresponding ID
$multi_array[1]['scores'] = array(2, 0, 6, 5);
$multi_array[2]['scores'] = array(3, 8, 0, 1);
$multi_array[3]['scores'] = array(4, 8, 6, 0);

for ($i = 0; $i < $member_count; ++$i){
	for ($j = 0; $j < $member_count; ++$j){
	if ($i == $j) continue;
	if ($multi_array[$j]['scores'][$i] == $multi_array[$i]['scores'][$j]) {// test for tie
		++$multi_array[$j]['ties'];} 
		elseif ($multi_array[$j]['scores'][$i] > $multi_array[$i]['scores'][$j])
			++$multi_array[$j]['wins'];
	}
	}
for ($i = 0; $i < $member_count; ++$i)
	echo 'Player Number '.($i+1).' has '.$multi_array[$i]['wins'].
        ' wins, and '.$multi_array[$i]['ties'].' ties.<br />';
// I do NOT use the player number, but 0 to 3, you get the player number by adding one

?>

Open in new window

0
 

Author Comment

by:duder78
ID: 34899016
Thanks alot!  I have stuff to do this afternoon but i'll try that out when I have the chance.  _THANK YOU_
0
 

Author Closing Comment

by:duder78
ID: 34899339
THANK YOU!  I'm about to leave for the afternoon but had an hour to try out your code using my test set and IT WORKS.  Dude, you're the BEST.  Being able to add wins to the stats without using a form makes the site much more robust and useful.  Thanks also to everyone who took the time to try and help me out, I know that I was not clear on alot of the specifics and made things difficult to understand.

Man, the monthly fee here is definitely worth it!
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now