?
Solved

logic problem

Posted on 2011-02-12
20
Medium Priority
?
303 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 111

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
7 Extremely Useful Linux Commands for Beginners

Just getting started with Linux? Here's a quick start guide that has 7 commands that we believe will come in handy.

 

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 111

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
 

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 111

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 34

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 34

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 34

Accepted Solution

by:
Slick812 earned 2000 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 does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
3 proven steps to speed up Magento powered sites. The article focus is on optimizing time to first byte (TTFB), full page caching and configuring server for optimal performance.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses

770 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