/*programeeropdracht 4 The Nim Game *Pascal de Vos (ID = 0446916) *Rick van der Zwet (ID = 0433373) *file: mainForm.cc *mainForm.cc, het hoofdprogramma hierin worden alle aanroepen behandeld *en wordt het menu opgebouwd */ #include "mainForm.h" #include "optionsForm.h" #include "stapelGroupBox.h" #include "nimSpel.h" #include "const.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include MainForm::MainForm( ) //constructor : QMainWindow( 0, 0, WDestructiveClose) { //global variablen standard value for(int i = 0; i < MAX_STAPELS; i++) { stapelBox[i] = NULL; } stapelAantal = -1; stokjesMin = 0; stokjesMax = 0; niveauComputer = 0; spelData = new NimSpel(); //end standard value setCaption( tr( "The Nim Game" ) ); //menubar QAction *fileNewAction; QAction *fileQuitAction; fileNewAction = new QAction( "New Game", "&New", CTRL+Key_N,this, "new"); connect( fileNewAction, SIGNAL( activated() ), this, SLOT( fileNew() ) ); fileQuitAction = new QAction( "Quit", "&Quit", CTRL+Key_Q, this, "quit" ); connect( fileQuitAction, SIGNAL( activated() ), this, SLOT( fileQuit() ) ); fileMenu = new QPopupMenu( this ); menuBar()->insertItem( "&File", fileMenu ); fileNewAction->addTo( fileMenu ); fileQuitAction->addTo ( fileMenu ); QAction *helpAboutAction; QAction *helpAboutQtAction; helpAboutAction = new QAction( "&About", "&About", CTRL+Key_H,this, "about"); connect( helpAboutAction, SIGNAL( activated() ), this, SLOT( helpAbout() ) ); helpAboutQtAction = new QAction( "AboutQt", "AboutQt", CTRL+Key_A,this, "aboutQt"); connect( helpAboutQtAction, SIGNAL( activated() ), this, SLOT( helpAboutQt() ) ); helpMenu = new QPopupMenu( this ); menuBar()->insertItem( "&Help", helpMenu ); helpAboutAction->addTo ( helpMenu ); helpAboutQtAction->addTo ( helpMenu ); //end menubar //winnend winnendFrame = new QFrame( this, "winnendFrame" ); winnendFrame->setEnabled( TRUE ); winnendFrame->setGeometry( QRect( 11, 31, 234, 138 ) ); winnendFrame->setFrameShape( QFrame::StyledPanel ); winnendFrame->setFrameShadow( QFrame::Plain ); winnendAantalLCDNumber = new QLCDNumber( winnendFrame, "winnendAantalLCDNumber" ); winnendAantalLCDNumber->setGeometry( QRect( 110, 80, 60, 41 ) ); winnendAantalLCDNumber->setNumDigits( 2 ); winnendAantalLCDNumber->setProperty( "intValue", 0 ); winnendStapelLCDNumber = new QLCDNumber( winnendFrame, "winnendStapelLCDNumber" ); winnendStapelLCDNumber->setGeometry( QRect( 10, 80, 61, 41 ) ); winnendStapelLCDNumber->setNumDigits( 2 ); winnendStapelTextLabel = new QLabel( winnendFrame, "winnendStapelTextLabel" ); winnendStapelTextLabel->setGeometry( QRect( 20, 50, 52, 20 ) ); winnendStapelTextLabel->setText( tr( "

Stapel

" ) ); winnendAantalTextLabel = new QLabel( winnendFrame, "winnendAantalTextLabel" ); winnendAantalTextLabel->setGeometry( QRect( 120, 50, 52, 20 ) ); winnendAantalTextLabel->setText( tr( "

Aantal

" ) ); winnendCheckBox = new QCheckBox( winnendFrame, "winnendCheckBox" ); winnendCheckBox->setGeometry( QRect( 10, 20, 170, 20 ) ); winnendCheckBox->setText( tr( "\"Winnende\" zet laten zien" ) ); winnendEnable( 0 ); //het disable van alle blokjes, begin waarde //end winnend //compDialog compDialogFrame = new QFrame( this, "compDialogFrame" ); compDialogFrame->setEnabled( TRUE ); compDialogFrame->setGeometry( QRect( 270, 31, 180, 138 ) ); compDialogFrame->setFrameShape( QFrame::StyledPanel ); compDialogFrame->setFrameShadow( QFrame::Plain ); compDialogFrame->hide(); compDialogStapelLCDNumber = new QLCDNumber( compDialogFrame, "compDialogStapelLCDNumber" ); compDialogStapelLCDNumber->setGeometry( QRect( 10, 50, 61, 41 ) ); compDialogStapelLCDNumber->setNumDigits( 2 ); compDialogStapelTextLabel = new QLabel( compDialogFrame, "compDialogStapelTextLabel" ); compDialogStapelTextLabel->setGeometry( QRect( 20, 20, 52, 20 ) ); compDialogStapelTextLabel->setText( tr( "

Stapel

" ) ); compDialogAantalLCDNumber = new QLCDNumber( compDialogFrame, "compDialogAantalLCDNumber" ); compDialogAantalLCDNumber->setGeometry( QRect( 100, 50, 60, 41 ) ); compDialogAantalLCDNumber->setNumDigits( 2 ); compDialogAantalLCDNumber->setProperty( "intValue", 0 ); compDialogAantalTextLabel = new QLabel( compDialogFrame, "compDialogAantalTextLabel" ); compDialogAantalTextLabel->setGeometry( QRect( 110, 20, 52, 20 ) ); compDialogAantalTextLabel->setText( tr( "

Aantal

" ) ); compDialogPushButton = new QPushButton( compDialogFrame, "compDialogPushButton" ); compDialogPushButton->setGeometry( QRect( 11, 100, 160, 31 ) ); compDialogPushButton->setText( tr( "OK, verwerk computerzet" ) ); //end compDialog //terugzetten terugzettenFrame = new QFrame( this, "terugzettenFrame" ); terugzettenFrame->setGeometry( QRect( 480, 31, 234, 138 ) ); terugzettenFrame->setFrameShape( QFrame::StyledPanel ); terugzettenFrame->setFrameShadow( QFrame::Plain ); terugzettenProgressBar = new QProgressBar( terugzettenFrame, "terugzettenProgressBar" ); terugzettenProgressBar->setGeometry( QRect( 20, 80, 190, 22 ) ); terugzettenProgressBar->setTotalSteps( 1 ); terugzettenProgressBar->setIndicatorFollowsStyle( TRUE ); terugzettenLCDNumber = new QLCDNumber( terugzettenFrame, "terugzettenLCDNumber" ); terugzettenLCDNumber->setGeometry( QRect( 20, 30, 190, 40 ) ); terugzettenLCDNumber->setNumDigits( 2 ); terugzettenLCDNumber->setProperty( "intValue", 0 ); terugzettenSlider = new QSlider( terugzettenFrame, "terugzettenSlider" ); terugzettenSlider->setGeometry( QRect( 20, 10, 190, 20 ) ); terugzettenSlider->setOrientation( QSlider::Horizontal ); terugzettenSlider->setTickmarks( QSlider::NoMarks ); terugzettenSlider->setRange( 0, 0); terugzettenPushButton = new QPushButton( terugzettenFrame, "terugzettenPushButton" ); terugzettenPushButton->setGeometry( QRect( 130, 110, 100, 21 ) ); terugzettenPushButton->setText( tr( "&Terug Zetten" ) ); terugzettenPushButton->setAccel( QKeySequence( tr( "Alt+T" ) ) ); //end terugzetten statusBar()->message( "Welcome to Nim"); resize( QSize(720, 768).expandedTo(minimumSizeHint()) ); clearWState( WState_Polished ); //connections connect( winnendCheckBox, SIGNAL ( stateChanged(int) ), this, SLOT ( winnendEnable(int) ) ); connect( compDialogPushButton, SIGNAL( clicked() ), this, SLOT ( computerZet() ) ); connect( terugzettenSlider, SIGNAL( valueChanged(int) ), terugzettenLCDNumber, SLOT( display(int) ) ); connect( terugzettenSlider, SIGNAL( valueChanged(int) ), terugzettenProgressBar, SLOT( setProgress( int ) ) ); connect( terugzettenPushButton, SIGNAL( clicked() ), this, SLOT ( terugZetten() ) ); this->show(); fileNew(); //om te zorgen dat gelijk in het begin het optiescherm //wordt geopend } //end MainForm::MainForm MainForm::~MainForm() //destructor { } //end MainForm:~MainForm //SLOTS void MainForm::fileNew() //creer new speelveld { OptionsForm * optionsForm = new OptionsForm( this ); if ( optionsForm->exec() ) { clearBord( stapelAantal, 0 , 0 ); int stapelAantalOptions = optionsForm->stapelsSlider->value(); int stokjesMinOptions = 0; int stokjesMaxOptions = optionsForm->stokjesSlider->value(); if ( optionsForm->niveau1RadioButton->isChecked() ) { niveauComputer = 1; } else if (optionsForm->niveau2RadioButton->isChecked() ) { niveauComputer = 2; } createBord( stapelAantalOptions, stokjesMinOptions, stokjesMaxOptions ); } delete optionsForm; } //end MainForm::fileNew void MainForm::fileQuit() //verlaat applicatie { qApp->exit ( 0 ); } //end MainForm::fileQuit void MainForm::helpAbout() //laat about venster zien { QMessageBox::about( this, "The Nim Game -- About", "Dit simpele spelletje was programeeropdracht nummer 4\n" "van de Universiteit Leiden\n" "\n" "U kunt dit spel enkel tegen de computer spelen\n" "U neemt om de beurt 1 of 2 stokjes van de stapel\n" "U kunt winnen door het laatste stokje van het veld weg te nemen\n" "\n" "Heel veel speelsplezier,\n" "Pascal de Vos, Rick van der Zwet\n" ); } void MainForm::helpAboutQt() //laat aboutQt venster zien { QMessageBox::aboutQt( this, "The Nim Game -- About Qt" ); } //end MainForm::helpAboutQt void MainForm::winnendEnable( int state ) //laat winnend venster oplichten { winnendAantalTextLabel->setEnabled( state ); winnendAantalLCDNumber->setEnabled( state ); winnendStapelTextLabel->setEnabled( state ); winnendStapelLCDNumber->setEnabled( state ); updateWinnend( ); } //end MainForm::winnendEnable void MainForm::computerZet( ) //computerzet doorvoeren { updateStapelBox( compStapelNummer, compAantalPakken, 2); computerDialog( false ); } //end MainForm::computerZet void MainForm::terugZetten( ) //zet x aantal zetten terug { int tmpAantal = 0; spelData->zetTerug( terugzettenSlider->value() ); for( int i = 0; i < stapelAantal; i++ ) { tmpAantal = spelData->aantalOpStapel( i ); stapelBox[i]->stapelProgressBar->reset(); stapelBox[i]->stapelProgressBar->setProgress( tmpAantal ); stapelBox[i]->stapelLCDNumber->display ( tmpAantal ); if (tmpAantal > 0) { //als 0 was waren de buttons uit, nu dus weer aan zetten stapelBox[i]->stapelMin1PushButton->setEnabled ( true ); stapelBox[i]->stapelMin2PushButton->setEnabled ( true ); } } updateWinnend(); updateTerugzetten(); } //end MainForm::terugZetten void MainForm::stapelBoxPressedMinButton( int stapelNummer , int aantalPakken ) //Functie wordt aangeroepen door de knoppen op het spelveld, hier worden //deze gegevens verwerkt en de computerzet berekend { updateStapelBox( stapelNummer, aantalPakken, 1 ); //eigen zet doorwerken if ( spelData->afgelopen() != true ){ spelData->computerZet( niveauComputer, compStapelNummer, //computerzet uitrekenen compAantalPakken ); if ( compStapelNummer == -1 ) { for ( int i = 0; i < stapelAantal; i++ ) { if ( spelData->aantalOpStapel(i) != 0 ) { compAantalPakken = 1; compStapelNummer = i; break; } } } computerDialog( true );//computerdialog laten zien } } //END SLOTS //maak het spelveld leeg, maw verwijder de stapels void MainForm::clearBord( int stapelAantalLocal, int stokjesMinLocal, int stokjesMaxLocal ) { spelData->beginWaarden( stapelAantalLocal, stokjesMaxLocal-stokjesMinLocal ); stapelAantal = stapelAantalLocal; stokjesMin = stokjesMinLocal; stokjesMax = stokjesMaxLocal; for(int i = 0; i < stapelAantalLocal; i++) { if (not( stapelBox[i] == NULL )) {delete stapelBox[i];} } } //end MainForm::clearBord //maak nieuw spelbord, maw maak nieuwe stapels void MainForm::createBord( int stapelAantalLocal, int stokjesMinLocal, int stokjesMaxLocal ) { int Y = 100; //xcoord int X = 11; //ycoord int tmpAantal = 0; //aantal onthouden ivm met rijen spelData->beginWaarden( stapelAantalLocal, stokjesMaxLocal-stokjesMinLocal ); stapelAantal = stapelAantalLocal; stokjesMin = stokjesMinLocal; stokjesMax = stokjesMaxLocal; for(int i = 0; i < stapelAantalLocal; i++) { if (tmpAantal == 7) { X = X + 360; Y = 170; tmpAantal = 1; } else { tmpAantal++; Y = Y + 70; } stapelBox[i] = new StapelGroupBox( this, "stapelGroupBox" ); stapelBox[i]->setXY( X, Y ); stapelBox[i]->setRange( stokjesMinLocal, stokjesMaxLocal ); stapelBox[i]->setCaption(i); connect( stapelBox[i], SIGNAL( buttonPressed(int,int) ), this, SLOT( stapelBoxPressedMinButton(int,int) ) ); stapelBox[i]->show(); } updateTerugzetten(); updateWinnend(); resize( QSize(720, 768).expandedTo(minimumSizeHint()) ); clearWState( WState_Polished ); } //end MainForm::createBord void MainForm::updateWinnend( ) //werk het winnend frame bij { int tmpStapel = 0; int tmpAantal = 0; if ( winnendAantalTextLabel->isEnabled() ) { spelData->winnend( tmpStapel, tmpAantal ); } else { tmpStapel = -8; tmpAantal = -8; } winnendStapelLCDNumber->display(tmpStapel); winnendAantalLCDNumber->display(tmpAantal); } //end MainForm::updateWinnend void MainForm::updateTerugzetten( ) //werk terugzetten frame bij { int aantalBeurten = spelData->aantalBeurten(); terugzettenSlider->setRange( 0, aantalBeurten ); terugzettenProgressBar->setTotalSteps( aantalBeurten ); } //end MainForm::updateTerugzetten void MainForm::winstDialog( int spelerNummer ) { //laat een kleine melding zien als iemand gewonnen heeft if ( spelerNummer == 1 ) { statusBar()->message("Voila, u heeft gewonnen!"); } else if ( spelerNummer == 2 ) { statusBar()->message("Helaas, computer heeft gewonnen"); } } //end MainForm::gewonnen void MainForm::updateStapelBox(int stapelNummer, int aantalPakken, int spelerNummer ) //Aanroepen Bijwerken van LCDNumber, ProgressBar, winnend , //terugzetten en spelData { //grafisch int tmpOudAantal = spelData->aantalOpStapel( stapelNummer ); int tmpNieuwAantal = 0; if (aantalPakken > tmpOudAantal) { aantalPakken = tmpOudAantal; } if (tmpOudAantal == aantalPakken) { tmpNieuwAantal = 0; stapelBox[stapelNummer]->stapelMin1PushButton->setEnabled ( FALSE ); stapelBox[stapelNummer]->stapelMin2PushButton->setEnabled ( FALSE ); } else { tmpNieuwAantal = tmpOudAantal - aantalPakken; } stapelBox[stapelNummer]->stapelLCDNumber->display( tmpNieuwAantal ); stapelBox[stapelNummer]->stapelProgressBar->reset(); stapelBox[stapelNummer]->stapelProgressBar->setProgress( tmpNieuwAantal ); //spelData bijwerken spelData->pakWeg( stapelNummer, aantalPakken ); updateTerugzetten(); if ( spelData->afgelopen() ) { winstDialog( spelerNummer ); } else { updateWinnend(); } } //end MainForm::updateStapelBox void MainForm::computerDialog( bool enabled ) { //als de computer dialog aan is, dan mag de gebruiker daar knoppen indrukken, de //rest is dan niet zichtbaar if ( enabled ){ for ( int i = 0;i < stapelAantal; i++ ) { stapelBox[i]->stapelMin1PushButton->hide ( ); stapelBox[i]->stapelMin2PushButton->hide ( ); } terugzettenPushButton->hide ( ); compDialogStapelLCDNumber->display( compStapelNummer ); compDialogAantalLCDNumber->display( compAantalPakken ); compDialogFrame->show( ); } else { for ( int i = 0;i < stapelAantal; i++ ) { stapelBox[i]->stapelMin1PushButton->show ( ); stapelBox[i]->stapelMin2PushButton->show ( ); } terugzettenPushButton->show ( ); compDialogFrame->hide( ); } } //end MainForm::computerDialog