examples/Bluetooth/BTExample1/src/player.cpp

00001 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 //
00015 
00016 #include <e32cons.h>
00017 #include <es_sock.h>
00018 
00019 #include "player.h"
00020 #include "cardgameplayer.h"
00021 
00022 
00026 CScabbyQueenPlayer* CScabbyQueenPlayer::NewL(CConsoleBase& aConsole, RSocket& aSocket)
00027         {
00028         CScabbyQueenPlayer* self = new CScabbyQueenPlayer(aConsole, aSocket);
00029         self->ConstructL();
00030         return self;
00031         }
00032 
00033 
00037 CScabbyQueenPlayer::CScabbyQueenPlayer(CConsoleBase& aConsole, RSocket& aSocket)
00038                                                 :iConsole(aConsole)
00039                                         
00040         {
00041         TRAPD(err,CCardGamePlayer::ConstructL(aSocket));
00042         }
00043 
00047 CScabbyQueenPlayer::~CScabbyQueenPlayer()
00048         {
00049         iHand.Close();
00050         }
00051 
00055 void CScabbyQueenPlayer::ConstructL()
00056         {
00057         iHand.Create(KDeckBufferLength);
00058         iRecvMode = EPlayerRecvNum;
00059         iCheckSize.Create(iPlayerNum);
00060         BaseRecvFrom(iPlayerNum);
00061         iCheckSize.Close();
00062         iGameOverBuffer = KErrCompletion;
00063         }
00064         
00065 void CScabbyQueenPlayer::RecvOfPlayerNumComplete()
00066         {
00067         iRecvMode = EPlayerRecvHand;
00068         BaseRecvFrom(iHand);
00069         StartTimer(KMaxRecvTime);
00070         }
00071 
00072 
00073 void CScabbyQueenPlayer::SendComplete(TInt aError)
00074         {
00075         switch (iSendMode)
00076                 {
00077                 case ESendReadyForUpdate:
00078                         SendReadyForUpdateComplete();
00079                 break;
00080                 
00081                 case ESendRecvTokenSuccess:
00082                         SentTokenRecvSuccess();
00083                 break;
00084                 
00085                 case ESendCardRecvNotification:
00086                         SentCardRecvNotification();
00087                 break;
00088                 
00089                 case ESendGameStatus:
00090                         SentGameStatus();
00091                 break;
00092                 
00093                 case ESendReadyForToken:
00094                         SentReadyForToken();
00095                 break;
00096                 
00097                 case ESendCardNumber:
00098                         SendOfCardNumberComplete();
00099                 break;
00100                 
00101                 case ESendOwnHandSize:
00102                         SendOfHandSizeComplete();
00103                 break;
00104                 
00105                 case ESendPlayerCard:
00106                         SendCardComplete();
00107                 break;
00108                         
00109                 case EPlayerSendAckSendCard:
00110                         SendCard();
00111                 break;
00112                         
00113                 case EPlayerSendAckRecvHandSize:
00114                         PrepareToSendCard();
00115                 break;
00116                         
00117                 case EPlayerSendAckRecvCard:
00118                         RecvOfCardComplete();
00119                 break;
00120                 
00121                 case EPlayerSendAckRecvWait:
00122                         AckSentAfterRecvWait(aError);
00123                 break;
00124                 default:
00125                 break;
00126                 }
00127         }
00128                 
00129 
00130 void CScabbyQueenPlayer::RecvComplete(TInetAddr /*aRecvAddr*/, TInt /*aError*/)
00131         {
00132 
00133         switch (iRecvMode)
00134                 {
00135                 case EPlayerRecvNum:
00136                         RecvOfPlayerNumComplete();
00137                 break;
00138                 
00139                 case EPlayerRecvHand:
00140                         RecvOfHandComplete();
00141                 break;
00142                 
00143                 case EPlayerRecvStatus:
00144                         RecvOfPlayTokenComplete();
00145                 break;
00146                 
00147                 case EGameStatus:
00148                         SendGameStatus();
00149                 break;
00150                 
00151                 case EPlayerUpdate:
00152                         ReceiveNextRole();
00153                 break;
00154                 
00155                 case EDealerReady:
00156                         RecvUpdate();
00157                 break;
00158                 
00159                 case ERecvHandSize:
00160                         RecvHandSize();
00161                 break;
00162                 
00163                 case ERecvCardNum:
00164                         SendCard();
00165                 break;
00166                 
00167                 case ERecvCard:
00168                         RecvOfCardComplete();
00169                 break;
00170 
00171                 default:
00172                         break;
00173                 }
00174         }
00175         
00176 
00181 void CScabbyQueenPlayer::RecvOfHandComplete()
00182         {
00183         StopTimer();
00184         if (iHand == iGameOverBuffer)
00185                 {
00186                 // We haven't recieved our hand but a game over message.
00187                 iConsole.Printf(_L("\nGAME OVER"));
00188                 }
00189         else
00190                 {
00191                 TInt handLength = iHandLength();
00192                 iHand.SetLength(handLength);
00193                 iConsole.Printf(_L("\n%d cards received."), handLength/2);
00194                 FindPairsAndRemove();
00195                 //Wait to receive notification of what we are doing (token)
00196                 iRecvTimerSet = ETrue;
00197                 iRecvMode = EPlayerRecvStatus;
00198                 iCheckSize.Create(iStatusBuffer);
00199                 BaseRecvFrom(iStatusBuffer);
00200                 iCheckSize.Close();
00201                 // we should now have our hand
00202                 }
00203 
00204         }
00205         
00206 
00207 
00213 void CScabbyQueenPlayer::RecvOfPlayTokenComplete()
00214         {
00215         // We have been called because we have been told that we are the current player
00216         StopTimer();
00217         if (iStatusBuffer == iGameOverBuffer)
00218                 {
00219                 // We haven't recieved our hand but a game over message.
00220                 iConsole.Printf(_L("\nGAME OVER"));
00221                 }
00222         else
00223                 {
00224                 iCurrentStatus = iStatusBuffer();
00225                 switch (iCurrentStatus)
00226                         {
00227                         case EWaiting:
00228                                 iConsole.Printf(_L("\nYou are not in play this time"));
00229                                 // need to wait to recv size of the update, then continue as with 
00230                                 // the other two players.
00231                                 iRecvMode = EDealerReady; // this will then call RecvUpdate
00232                                 iCheckSize.Create(iUpdateSize);
00233                                 BaseRecvFrom(iUpdateSize);
00234                                 iCheckSize.Close();
00235                                 // Send Ack back to dealer
00236                                 iAck = KErrNone;
00237                                 iSendMode = EPlayerSendAckRecvWait;
00238                                 BaseSendTo(iAck, KDealerIpAddr);
00239                         break;
00240                         
00241                         case EReceiving:
00242                                 {
00243                                 // we need to set card reciever
00244                                 iAck = KErrNone;
00245                                 iSendMode = ESendRecvTokenSuccess;
00246                                 BaseSendTo(iAck, KDealerIpAddr);
00247                                 }
00248                         break;
00249                         
00250                         case ESending:
00251                                 {
00252                                 iConsole.Printf(_L("\nYou are not in play this time"));
00253                                 SendHandSize();
00254                                 }
00255                         break;
00256                         
00257                         default:
00258                         break;
00259                         }
00260                 }
00261         }
00262 
00263 
00264 
00270 void CScabbyQueenPlayer::SendHandSize()
00271         {
00272         // send the size of our hand
00273         iSendMode = ESendOwnHandSize;
00274         iOwnHandSize = iHand.Length();
00275         BaseSendTo(iOwnHandSize, KDealerIpAddr);
00276         }
00277 
00278 
00279 
00285 void CScabbyQueenPlayer::SendOfHandSizeComplete()
00286         {
00287         // they have recv'd our hand size, proceed and setup recv of card num 
00288         iRecvMode = ERecvCardNum;
00289         iCheckSize.Create(iCardNum);
00290         BaseRecvFrom(iCardNum);
00291         iCheckSize.Close();
00292         }
00293         
00294 
00300 void CScabbyQueenPlayer::TimerComplete()
00301         {
00302         iConsole.Printf(_L("\nTimed out!"));
00303         iConsole.Printf(_L("\nWaited too long to hear from the dealer, sorry."));
00304         }
00305 
00311 void CScabbyQueenPlayer::SentTokenRecvSuccess()
00312         {
00313         // Get ready to receive hand size
00314         // We don't care if there was an error in sending because the 
00315         // Dealer will inform us next time of a Game Over
00316         iRecvMode = ERecvHandSize;
00317         iCheckSize.Create(iPeerHandSize);
00318         BaseRecvFrom(iPeerHandSize);
00319         iCheckSize.Close();
00320         }
00321 
00326 void CScabbyQueenPlayer::RecvHandSize()
00327         {
00328         if (iPeerHandSize == iGameOverBuffer)
00329                 {
00330                 // We have receved a game over message
00331                 iConsole.Printf(_L("\nGAME OVER"));
00332                 }
00333         else
00334                 {
00335                 iSendMode = EPlayerSendAckRecvHandSize;
00336                 iAck = KErrNone;
00337                 BaseSendTo(iAck, KDealerIpAddr);
00338                 // now we will go back to the menu and we will give the option to send a card number
00339                 }
00340 
00341         }
00342 
00347 void CScabbyQueenPlayer::PrepareToSendCard()
00348         {
00349         // We have sent the ack to say we have receive the peer hand size.
00350         iCurrentPlayer = ETrue;
00351         iConsole.Printf(_L("\nPress any key..."));
00352         }
00353 
00354 
00358 void CScabbyQueenPlayer::ShowHandL()
00359         {
00360         TInt cardNum;
00361         iConsole.Printf(_L("\nYour hand...\n"));
00362         for (TInt i=0; i<=iHand.Length()-2; i=i+2)
00363                 {
00364                 if (i==0)
00365                         cardNum = i;
00366                 else
00367                         cardNum = i/2;
00368                 HBufC16* buffer = HBufC16::NewL(4);
00369                 CleanupStack::PushL(buffer);
00370                 buffer->Des().Copy(iHand.Mid(i,2));
00371                 iConsole.Printf(_L("%d <%S>|"),cardNum,buffer);
00372                 CleanupStack::PopAndDestroy(buffer);
00373                 }
00374         iConsole.Getch();
00375         }
00376 
00381 void CScabbyQueenPlayer::FindPairsAndRemove()
00382         {
00383         TInt lastCardIndex = iHand.Length();
00384         while (lastCardIndex >= 4)
00385                 {
00386                 lastCardIndex = lastCardIndex-KCardLength;
00387                 TPtrC8 ptrWholeCard = iHand.Mid(lastCardIndex, KCardLength);// pointer to last card
00388                 TPtrC8 ptr = iHand.Mid(lastCardIndex);// pointer to value of last card
00389                 TInt result = iHand.Locate(ptr[0]);// search the hand for duplicate
00390                 if (result == lastCardIndex)
00391                         {
00392                         // This card is unique
00393                         // no match was found, dont throw away
00394                         }
00395                 else
00396                         {
00397                         // we have a match!
00398                         iHand.Delete(lastCardIndex, KCardLength);// delete the last card
00399                         iHand.Delete(result, KCardLength);// delete the card that matched it
00400                         // we have removed an extra card, index of last will now be 2 less
00401                         lastCardIndex = lastCardIndex-KCardLength;
00402                         }
00403                 }
00404 
00405         }
00406 
00410 void CScabbyQueenPlayer::GetRightHandPlayerCard()
00411         {
00412         TInt numOfCards = iPeerHandSize()/2;
00413         iConsole.Printf(_L("Select a card between 0 - %d: "), numOfCards-1);
00414         }
00415 
00416         
00421 TInt CScabbyQueenPlayer::SendCardNum(TInt aCardNum)
00422         {
00423         
00424         if (aCardNum >= iPeerHandSize())
00425                 {
00426                 iConsole.Printf(_L("\nInvalid selection, try again numb nuts"));
00427                 return (KErrTooBig);    
00428                 }
00429         else
00430                 {
00431                 // Get ready to recv 
00432                 iCardNum = aCardNum;
00433                 iSendMode = ESendCardNumber;
00434                 BaseSendTo(iCardNum, KDealerIpAddr);
00435                 }
00436 
00437         return (KErrNone);
00438         }
00439         
00440 
00445 void CScabbyQueenPlayer::SendOfCardNumberComplete()
00446         {
00447         // now recv card
00448         // This function is called as soon as Send of card num to the dealer
00449         // has completed. We wont error check as dealer will tell us if game is over
00450         iRecvMode = ERecvCard;
00451         BaseRecvFrom(iReceivedCard);
00452         }
00453         
00454 
00455 
00461 void CScabbyQueenPlayer::RecvOfCardComplete()
00462         {
00463         if (iReceivedCard == iGameOverBuffer)
00464                 {
00465                 // its true. the game is over.
00466                 BaseCancelRecvFrom();
00467                 iConsole.Printf(_L("\nDealer Says: GAME OVER"));
00468                 }
00469         else
00470                 {
00471                 iConsole.Printf(_L("Recevied Card"));
00472                 iCurrentPlayer = EFalse;
00473                 iHand.Append(iReceivedCard);//add card to hand
00474                 FindPairsAndRemove();// Check for pairs
00475                 if (iHand.Length() == 0)
00476                         iFinished = ETrue;
00477                 // Tell the dealer that we have received the card
00478                 // This is the ack that they are expecting
00479                 iSendMode = ESendCardRecvNotification;
00480                 iStatusBuffer = EReceivedCard;
00481                 BaseSendTo(iStatusBuffer, KDealerIpAddr);
00482                 }
00483         }
00484 
00485 
00491 void CScabbyQueenPlayer::SentCardRecvNotification()
00492         {
00493         // recv request to send our game status
00494         iRecvMode = EGameStatus;
00495         iCheckSize.Create(iGameStatus);
00496         BaseRecvFrom(iGameStatus);
00497         iCheckSize.Close();
00498         }
00499 
00500 
00506 void CScabbyQueenPlayer::RecvUpdate()
00507         {
00508         if (iUpdateSize == iGameOverBuffer)
00509                 {
00510                 // We were expecting an update size but got a game over
00511                 iConsole.Printf(_L("\nDealer Says: GAME OVER"));
00512                 }
00513         else
00514                 {
00515                 iPlayerUpdate.SetLength(iUpdateSize());// set size of update to size just recv from dealer
00516                 iGameStatus = EReadyForUpdate;
00517                 iSendMode = ESendReadyForUpdate;
00518                 BaseSendTo(iGameStatus, KDealerIpAddr);
00519                 }
00520 
00521         }
00522 
00523 
00528 void CScabbyQueenPlayer::SendReadyForUpdateComplete()
00529         {
00530         // Now we have said we are read for the update, get ready to receive it!
00531         iRecvMode = EPlayerUpdate;
00532         BaseRecvFrom(iPlayerUpdate);
00533         }
00534 
00535 
00539 void CScabbyQueenPlayer::SendGameStatus()
00540         {
00541 
00542         // Called after we have received game status request from dealer
00543         // Decide which player we are and send the necessary game status
00544         if (iGameStatus() == EGameStatusRequest)
00545                 {
00546                 switch (iPlayerNum())
00547                         {
00548                         case 0:
00549                                 if (iFinished)
00550                                         iGameStatus = EFinishedZero;
00551                                 else
00552                                         iGameStatus = EPlayingZero;
00553                         break;
00554                         
00555                         case 1:
00556                                 if (iFinished)
00557                                         iGameStatus = EFinishedOne;
00558                                 else
00559                                         iGameStatus = EPlayingOne;
00560                         break;
00561                                 
00562                         case 2:
00563                                 if (iFinished)
00564                                         iGameStatus = EFinishedTwo;
00565                                 else
00566                                         iGameStatus = EPlayingTwo;
00567                         break;
00568                                 
00569                         case 3:
00570                                 if (iFinished)
00571                                         iGameStatus = EFinishedThree;
00572                                 else
00573                                         iGameStatus = EPlayingThree;
00574                         break;
00575                                 
00576                         case 4:
00577                                 if (iFinished)
00578                                         iGameStatus = EFinishedFour;
00579                                 else
00580                                         iGameStatus = EPlayingFour;
00581                         break;
00582                         
00583                         case 5:
00584                                 if (iFinished)
00585                                         iGameStatus = EFinishedFive;
00586                                 else
00587                                         iGameStatus = EPlayingFive;
00588                         break;
00589                                 
00590                         case 6:
00591                                 if (iFinished)
00592                                         iGameStatus = EFinishedSix;
00593                                 else
00594                                         iGameStatus = EPlayingSix;
00595                         break;
00596 
00597                         case 7:
00598                                 if (iFinished)
00599                                         iGameStatus = EFinishedSeven;
00600                                 else
00601                                         iGameStatus = EPlayingSeven;
00602                         break;
00603                         }
00604                 iSendMode = ESendGameStatus;                    
00605                 BaseSendTo(iGameStatus, KDealerIpAddr);
00606                 }
00607                 
00608         else if (iGameStatus == iGameOverBuffer)
00609                 {
00610                 iConsole.Printf(_L("\nDealer Says: GAME OVER"));
00611                 }
00612         }
00613         
00614 
00619 void CScabbyQueenPlayer::SentGameStatus()
00620         {
00621         iRecvMode = EDealerReady; // this will then call RecvUpdate
00622         iCheckSize.Create(iUpdateSize);
00623         BaseRecvFrom(iUpdateSize);
00624         iCheckSize.Close();
00625         }
00626         
00632 void CScabbyQueenPlayer::ReceiveNextRole()
00633         {
00634         if (iPlayerUpdate == iGameOverBuffer)
00635                 {
00636                 iConsole.Printf(_L("\nDealer Says: GAME OVER"));
00637                 }
00638         else
00639                 {
00640                 // Break down the update descriptor and display the result
00641                 TBufC<20> buffer;
00642                 buffer.Des().Copy(iPlayerUpdate);       
00643                 iConsole.Printf(_L("\n\nUpdate from the dealer...%S\n"), &buffer);
00644                 TInt position;
00645                 TPtrC8 ptr(iPlayerUpdate);
00646                 TLex8 lex;
00647                 TInt player;
00648                 TBool stillIn = EFalse;
00649                 iConsole.Printf(_L("\n  Number of players: %d\n"), iPlayerUpdate.Length()-1);
00650         
00651                 TInt stillInCount = 0;
00652                 for (TInt i=0; i<iPlayerUpdate.Length();i++)
00653                         {
00654                         TChar inspect = ptr[i];
00655                 
00656                         if (inspect != 'F')
00657                                 {
00658                                 TBuf8<2> buff;
00659                                 buff.Append(inspect);
00660                                 lex.Assign(buff);
00661                                 lex.Val(player);
00662                                 
00663                                 if (stillIn)
00664                                         {
00665                                         TBufC16<2> buff;
00666                                         buff.Des().Append(inspect);
00667                                         iConsole.Printf(_L("\n  Player %S still in play"), &buff);
00668                                         stillInCount++;
00669                                         }
00670                                 else
00671                                         {
00672                                         position = i+1;
00673                                         if (i == 0)
00674                                                 {
00675                                                 iConsole.Printf(_L("\n The winner is player %d"), player);
00676                                                 }
00677                                         else
00678                                                 {
00679                                                 iConsole.Printf(_L("\n  In position %d is player %d"), position, player);
00680                                                 }
00681                                         }               
00682                                 }
00683                         else 
00684                                 {
00685                                 stillIn = ETrue;
00686                                 }
00687                         }
00688         
00689                 if (stillInCount == 1)
00690                         {
00691                         // If there is only one player left the game is over.
00692                         iGameOver = ETrue;
00693                         iConsole.Printf(_L("\nThe loser is player %d, give them a smack"), player);
00694                         iConsole.Printf(_L("\n\nDealer Says: GAME OVER"));
00695                         }
00696                 iGameStatus = EReadyForToken;
00697                 iSendMode = ESendReadyForToken;
00698                 BaseSendTo(iGameStatus, KDealerIpAddr);
00699                 }
00700         
00701         }
00702 
00703 
00708 void CScabbyQueenPlayer::SentReadyForToken()
00709         {
00710         // Told the dealer we are ready, setup Recv of our next status
00711         iRecvMode = EPlayerRecvStatus;
00712         iCheckSize.Create(iStatusBuffer);
00713         BaseRecvFrom(iStatusBuffer);
00714         iCheckSize.Close();
00715         }
00716 
00717 
00722 void CScabbyQueenPlayer::SendCard()
00723         {
00724         // we have ack'd the send of card num from the dealer.
00725                 
00726         if (iCardNum == iGameOverBuffer)
00727                 {
00728                 // dealer has told us that we have lost a player
00729                 // and that the game is over
00730                 iConsole.Printf(_L("Dealer Says: GAME OVER"));
00731                 }
00732         else
00733                 {               
00734                 // send the card requested
00735                 iSendMode = ESendPlayerCard;
00736                 TBuf8<2> buffer(iHand.Mid(iCardNum(),2));
00737                 BaseSendTo(buffer, KDealerIpAddr);
00738                 
00739                 }
00740 
00741         }
00742 
00743 
00747 void CScabbyQueenPlayer::SendAckAfterRecvCard()
00748         {
00749         //deler is expecting an ack to show that we have received the card
00750         iAck = KErrNone;
00751         iSendMode = EPlayerSendAckRecvCard;
00752         BaseSendTo(iAck, KDealerIpAddr);
00753         }
00754         
00760 void CScabbyQueenPlayer::SendCardComplete()
00761         {
00762         // Send of card has completed
00763         iHand.Delete(iCardNum(),2);// delete card from hand
00764         if (iHand.Length() == 0)
00765                 iFinished = ETrue;
00766         iRecvMode = EGameStatus;// recv request to send our game status
00767         iCheckSize.Create(iGameStatus);
00768         BaseRecvFrom(iGameStatus);
00769         iCheckSize.Close();
00770         }
00771         
00772 void CScabbyQueenPlayer::AckSentAfterRecvWait(TInt aError)
00773         {
00774         if (aError != KErrNone)
00775                 {
00776                 // The send of the ack has failed
00777                 // GAME OVER
00778                 BaseCancelRecvFrom();
00779                 iConsole.Printf(_L("\nDealer Says: GAME OVER"));
00780                 }
00781         }
00782         

Generated on Thu Jan 21 10:32:57 2010 for TB10.1 Example Applications by  doxygen 1.5.3