界面采用Qt實(shí)現(xiàn),非常簡(jiǎn)單而丑的界面。。。

cvp

pvc

功能全了,主要有:

1.CVP你想個(gè)數(shù)字,電腦來(lái)猜,每猜一次你需要告訴電腦?A?B

2.PVC電腦隨機(jī)生成數(shù)字,你來(lái)猜。

輸入框內(nèi)你可以修改備選的數(shù)字。

注意讓電腦猜的話,數(shù)字多了會(huì)非常慢。我的算法問(wèn)題。。。。

健壯性沒(méi)有考慮,所以,盡量正常玩吧^_^

PVC就不用說(shuō)了,隨機(jī)選數(shù)字然后提示給用戶幾A幾B就行。

CVP主要是開(kāi)始時(shí)生成一個(gè)可選集合(所有可能的數(shù)字),再根據(jù)用戶輸入一次次的縮小可選集。

接下來(lái)從可選集給出數(shù)字,給出的策略可以自己制定,我寫(xiě)了很簡(jiǎn)單的一種可能。

代碼里都分開(kāi)了,如果有人有興趣看的話應(yīng)該不會(huì)難看懂~看不懂或者哪里需要改進(jìn)的請(qǐng)給我留言O(shè)(∩_∩)O探討。

PVC的數(shù)據(jù)類

#ifndef ABComputerGuess_H
#define ABComputerGuess_H
#include <string>
#include <vector>
class ABComputerGuess {

public:
ABComputerGuess();
void init();
std::string getGuessAnswer();
void setAnswerABs(int ACounter, int BCounter);
void setBaseDigit(std::string base);
std::string getBaseDigit() { return baseDigits; }

private:
bool compareTwoStrings(const std::string &str1, const std::string &str2, int ACounter, int BCounter);
int compareTwoStrings(const std::string &str1, const std::string &str2);
std::string chooseAnswer();
private:
std::string baseDigits;
std::vector<std::string> maybeSource;
std::string mAnswer;
};
#endif//ABComputerGuess_H

PVC的視圖類

#ifndef ABCOMPUTERGUESSWIDGET_H
#define ABComputerGuessWidget_H
#include <QWidget>

class QLabel;
class QLineEdit;
class QPushButton;
class ABComputerGuess;

class ABComputerGuessWidget : public QWidget {

Q_OBJECT

public:
ABComputerGuessWidget(QWidget *parent = 0);

private slots:
void getABNumber();
void resetGame();

private:
void setGuessResult();

private:
ABComputerGuess *mABGuess;
QLineEdit *mACounterEdit;
QLineEdit *mBCounterEdit;
QLabel *mALabel;
QLabel *mBLabel;
QPushButton *mGuessButton;
QPushButton *mAgainButton;
QLabel *mResultShowingLabel;
QLineEdit *mBaseDigitEdit;
QString mAllResult;
};
#endif//ABComputerGuessWidget_H

CVP的數(shù)據(jù)類:

#ifndef ABPLAYERGUESS_H
#define ABPLAYERGUESS_H

#include <string>

class ABPlayerGuess {

public:
ABPlayerGuess();
void init();
std::string getBaseDigit() { return mBaseDigits; }
void setBaseDigit(std::string baseDigit) { mBaseDigits = baseDigit; }
std::string getRightAnswer() { return mRightNumber; }
void playerGuess(const std::string& str, int &ACounter, int &BCounter);

private:
int compareTwoStrings(const std::string &str1, const std::string &str2);

private:
std::string mRightNumber;
std::string mBaseDigits;
};
#endif//ABPLAYERGUESS_H

CVP的視圖類:

#ifndef    ABPLAYERGUESSWIDGET_H
#define ABPLAYERGUESSWIDGET_H

#include <QWidget>

class QLineEdit;
class QLabel;
class QPushButton;
class ABPlayerGuess;
class QRegExpValidator;

class ABPlayerGuessWidget : public QWidget {

Q_OBJECT

public:
ABPlayerGuessWidget(QWidget *parent = 0);

private slots:
void onGuessed();
void resetGame();
void showRightAnswer();

private:
ABPlayerGuess *mGuessChecker;
QLineEdit *mGuessEdit;
QLabel *mResultShowingLabel;
QPushButton *mGuessButton;
QPushButton *mAgainButton;
QPushButton *mCheckButton;
QLineEdit *mBaseDigit;
QRegExpValidator *mGuessRuler;
QString mAllResult;
};
#endif//ABPLAYERGUESSWIDGET_H

整體視圖類:

#ifndef ABGAMEWIDGET_H
#define ABGAMEWIDGET_H

#include <QTabWidget>
class ABComputerGuessWidget;
class ABPlayerGuessWidget;

class ABGameWidget : public QTabWidget {
Q_OBJECT

public:
ABGameWidget(QWidget *parent = 0);

private:
ABComputerGuessWidget *mComputerGuessWidget;
ABPlayerGuessWidget *mPlayerGuessWidget;
};
#endif//ABGAMEWIDGET_H

各個(gè)類的實(shí)現(xiàn):

#include <set>
#include "ABComputerGuess.h"
ABComputerGuess::ABComputerGuess() :
baseDigits("0123456789")
{
init();
}

void ABComputerGuess::init()
{
int len = baseDigits.size();
maybeSource.clear();
for ( int i=0; i<len; ++i)
for ( int j=0; j<len; ++j)
for ( int p=0; p<len; ++p)
for ( int q=0; q<len; ++q)
if (i!=j && i!=p && i!=q && j!=p && j!=q && p!=q) {
std::string temp;
temp.push_back(baseDigits[i]);
temp.push_back(baseDigits[j]);
temp.push_back(baseDigits[p]);
temp.push_back(baseDigits[q]);
maybeSource.push_back(temp);
}
}

std::string ABComputerGuess::getGuessAnswer()
{
if (maybeSource.size()==0)
return std::string("error!");
//mAnswer = maybeSource[0];
mAnswer = chooseAnswer();
return mAnswer;
}

void ABComputerGuess::setAnswerABs(int ACounter, int BCounter)
{
if (ACounter>=0&&ACounter<=4&&BCounter>=0&&BCounter<=4) {
std::vector<std::string>::iterator iter=maybeSource.begin();
while (iter!=maybeSource.end()) {
if (!compareTwoStrings(mAnswer, *iter, ACounter, BCounter))
iter = maybeSource.erase(iter);
else
++iter;
}
}
}

int ABComputerGuess::compareTwoStrings(const std::string &str1, const std::string &str2)
{
int acounter = 0;
int bcounter = 0;
for ( size_t i=0; i<str1.size(); ++i)
for ( size_t j=0; j<str2.size(); ++j) {
if (str1[i]==str2[j]) {
if (i==j) {
++acounter;
} else {
++bcounter;
}
}
}
return acounter*10+bcounter;

}
bool ABComputerGuess::compareTwoStrings(const std::string &str1, const std::string &str2, int ACounter, int BCounter)
{
int counter = compareTwoStrings(str1,str2);
int bcounter = counter%10;
int acounter = counter/10%10;

return ((ACounter==acounter) && (BCounter==bcounter));
}

void ABComputerGuess::setBaseDigit(std::string base)
{
baseDigits = base;
init();
}

std::string ABComputerGuess::chooseAnswer()
{
int len = baseDigits.size();
size_t maxResultKinds = 0;
bool isLastinmaybeSource = false;
std::string guessAnswer;
for ( int i=0; i<len; ++i)
for ( int j=0; j<len; ++j)
for ( int p=0; p<len; ++p)
for ( int q=0; q<len; ++q)
if (i!=j && i!=p && i!=q && j!=p && j!=q && p!=q) {
std::string temp;
temp.push_back(baseDigits[i]);
temp.push_back(baseDigits[j]);
temp.push_back(baseDigits[p]);
temp.push_back(baseDigits[q]);
std::set<int> resultSet;
size_t length = maybeSource.size();
for ( size_t i=0; i<length; ++i) {
resultSet.insert(compareTwoStrings(maybeSource[i],temp));
}
if (resultSet.size()>=maxResultKinds) {
bool isInMaybeSource = (resultSet.find(40)!=resultSet.end());
if (resultSet.size()==maxResultKinds) {
if (isInMaybeSource && !isLastinmaybeSource) {
isLastinmaybeSource = true;
guessAnswer = temp;
}
} else {
isLastinmaybeSource = isInMaybeSource;
guessAnswer = temp;
maxResultKinds = resultSet.size();
}
}
if (maxResultKinds==14 && isLastinmaybeSource) return guessAnswer;
}
return guessAnswer;
}

#include <string>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QIntValidator>
#include "ABComputerGuessWidget.h"
#include "ABComputerGuess.h"

ABComputerGuessWidget::ABComputerGuessWidget(QWidget *parent) :
QWidget(parent)
{
QHBoxLayout *leftTopLayout = new QHBoxLayout;
mACounterEdit = new QLineEdit(this);
mALabel = new QLabel("A", this);
mBCounterEdit = new QLineEdit(this);
mBLabel = new QLabel("B", this);
QIntValidator *validator = new QIntValidator(0,4,this);
mACounterEdit->setValidator(validator);
mBCounterEdit->setValidator(validator);
leftTopLayout->addWidget(mACounterEdit);
leftTopLayout->addWidget(mALabel);
leftTopLayout->addWidget(mBCounterEdit);
leftTopLayout->addWidget(mBLabel);

QVBoxLayout *leftLayout = new QVBoxLayout;
mResultShowingLabel = new QLabel(this);
leftLayout->addLayout(leftTopLayout);
leftLayout->addWidget(mResultShowingLabel);

mABGuess = new ABComputerGuess();

QVBoxLayout *rightLayout = new QVBoxLayout;
mGuessButton = new QPushButton("Guess",this);
mAgainButton = new QPushButton("Again",this);
mBaseDigitEdit = new QLineEdit(mABGuess->getBaseDigit().c_str(), this);
rightLayout->addWidget(mGuessButton);
rightLayout->addWidget(mAgainButton);
rightLayout->addWidget(mBaseDigitEdit);

QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);

setLayout(mainLayout);

setGuessResult();

connect(mACounterEdit, SIGNAL(returnPressed()), this, SLOT(getABNumber()));
connect(mBCounterEdit, SIGNAL(returnPressed()), this, SLOT(getABNumber()));
connect(mBaseDigitEdit, SIGNAL(returnPressed()), this, SLOT(resetGame()));
connect(mGuessButton, SIGNAL(clicked()), this, SLOT(getABNumber()));
connect(mAgainButton, SIGNAL(clicked()), this, SLOT(resetGame()));
}

void ABComputerGuessWidget::setGuessResult()
{
std::string guessNumber = mABGuess->getGuessAnswer();
mAllResult.append(guessNumber.c_str());
mResultShowingLabel->setText(mAllResult);
}

void ABComputerGuessWidget::getABNumber()
{
mABGuess->setAnswerABs(mACounterEdit->displayText().toInt(),
mBCounterEdit->displayText().toInt());
QString abNumberString = mACounterEdit->displayText() +
QString(1,'A') +
mBCounterEdit->displayText() +
QString(1,'B');
mAllResult.append(" | ").append(abNumberString).append("\n");
setGuessResult();
}

void ABComputerGuessWidget::resetGame()
{
mABGuess->setBaseDigit(mBaseDigitEdit->displayText().toUtf8().data());
mABGuess->init();
mAllResult.clear();
setGuessResult();
mACounterEdit->setText("");
mBCounterEdit->setText("");
}

#include <QLabel>
#include <QMessageBox>
#include "ABGameWidget.h"
#include "ABComputerGuessWidget.h"
#include "ABPlayerGuessWidget.h"
ABGameWidget::ABGameWidget(QWidget *parent) :
QTabWidget(parent)
{
mPlayerGuessWidget = new ABPlayerGuessWidget(this);
mComputerGuessWidget = new ABComputerGuessWidget(this);
addTab(mPlayerGuessWidget, tr("PVC"));
addTab(mComputerGuessWidget, tr("CVP"));
QLabel *infoLabel = new QLabel(tr("<b>AB Game:</b><br></br>\n\
1.PVC:computer will offer one number(secret at first).\n\
Guess the number by the xAxB responsed by computer.\n\
2.CVP:computer will guess the number you offered.\n\
And you should offer xAxB as the result,too.\n\
The base characters can be setted in the lineedit, input and pressed enter\n\
Contact me if you found some big error......email: izualzhy@163.com"
));
infoLabel->setTextFormat(Qt::PlainText);
addTab(infoLabel,tr("About"));
}


#include <stdlib.h>
#include <time.h>
#include "ABPlayerGuess.h"
ABPlayerGuess::ABPlayerGuess() :
mBaseDigits("0123456789")
{
//init();
}

void ABPlayerGuess::init()
{
int len = mBaseDigits.size();
mRightNumber.clear();
while (mRightNumber.size()!=4) {
char temp = mBaseDigits[rand()%len];
if (mRightNumber.find(temp)==std::string::npos)
mRightNumber.append(1,temp);
}
}

void ABPlayerGuess::playerGuess(const std::string &str, int &ACounter, int &BCounter)
{
int counter = compareTwoStrings(str, mRightNumber);
BCounter = counter%10;
ACounter = counter/10%10;
}

int ABPlayerGuess::compareTwoStrings(const std::string &str1, const std::string &str2)
{
int acounter = 0;
int bcounter = 0;
for ( size_t i=0; i<str1.size(); ++i)
for ( size_t j=0; j<str2.size(); ++j) {
if (str1[i]==str2[j]) {
if (i==j) {
++acounter;
} else {
++bcounter;
}
}
}
return acounter*10+bcounter;

}

#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QRegExpValidator>
#include "ABPlayerGuessWidget.h"
#include "ABPlayerGuess.h"
ABPlayerGuessWidget::ABPlayerGuessWidget(QWidget *parent) :
QWidget(parent)
{
mGuessChecker = new ABPlayerGuess;
QVBoxLayout *rightLayout = new QVBoxLayout;
mGuessEdit = new QLineEdit(this);
mGuessRuler = new QRegExpValidator(mGuessEdit);
mResultShowingLabel = new QLabel(this);
rightLayout->addWidget(mGuessEdit);
rightLayout->addWidget(mResultShowingLabel);

QVBoxLayout *leftLayout = new QVBoxLayout;
mGuessButton = new QPushButton("Guess",this);
mAgainButton = new QPushButton("Again",this);
mBaseDigit = new QLineEdit(mGuessChecker->getBaseDigit().c_str(),this);
mCheckButton = new QPushButton("Check",this);
leftLayout->addWidget(mGuessButton);
leftLayout->addWidget(mAgainButton);
leftLayout->addWidget(mBaseDigit);
leftLayout->addWidget(mCheckButton);

QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(rightLayout);
mainLayout->addLayout(leftLayout);
setLayout(mainLayout);
connect(mGuessEdit,SIGNAL(returnPressed()),this,SLOT(onGuessed()));
connect(mGuessButton,SIGNAL(clicked()),this,SLOT(onGuessed()));
connect(mAgainButton,SIGNAL(clicked()),this,SLOT(resetGame()));
connect(mCheckButton,SIGNAL(clicked()),this,SLOT(showRightAnswer()));
connect(mBaseDigit,SIGNAL(returnPressed()),this,SLOT(resetGame()));

resetGame();
}

void ABPlayerGuessWidget::onGuessed()
{
int a,b;
QString playerGuessString = mGuessEdit->displayText();
for ( int i=0; i<playerGuessString.size(); ++i)
for ( int j=0; j<playerGuessString.size(); ++j) {
if ((i!=j) && (playerGuessString[i]==playerGuessString[j]))
return;
}

mGuessChecker->playerGuess(playerGuessString.toUtf8().data(),a,b);
QString guessAnswer = QString::number(a) + QString(QChar('A'))
+ QString::number(b) + QString(QChar('B')) + QString(QChar('\n'));
mAllResult = playerGuessString.append(" | ").append(guessAnswer) + mAllResult;
mResultShowingLabel->setText(mAllResult);
mGuessEdit->setText("");
}

void ABPlayerGuessWidget::resetGame()
{
if (mBaseDigit->displayText().size()<4) {
mBaseDigit->setText("0123456789");
}
mGuessChecker->setBaseDigit(mBaseDigit->displayText().toUtf8().data());
mGuessChecker->init();
mGuessEdit->setText("");
mAllResult.clear();
mResultShowingLabel->setText(mAllResult);
QString rulerString = QString("[")+mBaseDigit->displayText()+QString("]{4}");
mGuessRuler->setRegExp(QRegExp(rulerString));
mGuessEdit->setValidator(mGuessRuler);
}

void ABPlayerGuessWidget::showRightAnswer()
{
QMessageBox::about(this,"Answer",mGuessChecker->getRightAnswer().c_str());
resetGame();
}