⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wordgame.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	    int lose=0;	    for ( int j=0; j<c; j++ )		lose += r->tileRef(j)->value();	    totalleft += lose;	    scoreinfo->addScore(i,-lose);	} else {	    out = i;	}    }    int highest=0;    int winner=0;    for (i=0; i<nplayers; i++) {	int s = scoreinfo->playerScore(i);	if ( s > highest ) {	    highest = s;	    winner = i;	}    }    if ( out >= 0 )	scoreinfo->addScore(out,totalleft);    scoreinfo->setBoldOne(winner);    gameover = TRUE;    done->setEnabled(TRUE);    reset->setEnabled(FALSE);}void WordGame::endTurn(){    if ( gameover ) {	openGameSelector(namelist);    } else {	if ( board->checkTurn() ) {	    if ( board->turnScore() >= 0 ) {		scoreinfo->addScore(player,board->turnScore());		board->finalizeTurn();	    } else {		QApplication::beep();	    }	    nextPlayer();	}    }}void WordGame::resetTurn(){    board->resetRack();}void WordGame::passTurn(){    // ######## trade?    nextPlayer();}bool WordGame::refillRack(int i){    Rack* r = rack(i);    while ( !bag->isEmpty() && !r->isFull() ) {	r->addTile(bag->takeRandom());    }    return r->count() != 0;}void WordGame::readyRack(int i){    Rack* r = rack(i);    racks->raiseWidget(i);    board->setCurrentRack(r);    done->setEnabled( !r->computerized() );    reset->setEnabled( !r->computerized() );    if ( r->computerized() ) {	cpu = new ComputerPlayer(board, r);	aiheart->start(0);    }}Rack* WordGame::rack(int i) const{    return racks ? (Rack*)racks->widget(i) : NULL;}void WordGame::think(){    if ( !cpu->step() ) {	delete cpu;	cpu = 0;	aiheart->stop();	if ( board->turnScore() < 0 )	    passTurn();	else	    endTurn();    }}ComputerPlayer::ComputerPlayer(Board* b, Rack* r) :    board(b), rack(r), best(new const Tile*[rack_tiles]),	best_blankvalues(new Tile[rack_tiles]){    best_score = -1;    across=FALSE;    dict=0;}ComputerPlayer::~ComputerPlayer(){    delete [] best;    delete [] best_blankvalues;}bool ComputerPlayer::step(){    const QDawg::Node* root = dict ? Global::dawg("WordGame").root()				: Global::fixedDawg().root();    QPoint d = across ? QPoint(1,0) : QPoint(0,1);    const Tile* tiles[99]; // ### max board size    uchar nletter[4095]; // QDawg only handles 0..4095    memset(nletter,0,4096);    for (int i=0; i<rack->count(); i++) {	const Tile* r = rack->tileRef(i);	if ( r->isBlank() )	    nletter[0]++;	else	    nletter[r->text()[0].unicode()]++;    }    Tile blankvalues[99]; // ### max blanks    findBest(current, d, root, 0, nletter, tiles, 0, blankvalues, 0);    if ( ++current.rx() == board->xTiles() ) {	current.rx() = 0;	if ( ++current.ry() == board->yTiles() ) {	    if ( across ) {		if ( dict == 1 ) {		    if ( best_score >= 0 ) {			rack->arrangeTiles(best,best_n);			rack->setBlanks(best_blankvalues);			board->scoreTurn(best_start, best_n, best_dir);			board->showTurn();		    }		    return FALSE;		}		dict++;		across = FALSE;		current = QPoint(0,0);	    } else {		across = TRUE;		current = QPoint(0,0);	    }	}    }    return TRUE;}void ComputerPlayer::findBest(QPoint at, const QPoint& d, const QDawg::Node* node, ulong used, uchar* nletter, const Tile** tiles, int n, Tile* blankvalues, int blused){    if ( !node )	return;    QChar l = node->letter();    const Tile* cur = board->tile(at);    if ( cur ) {	if ( cur->text()[0] == l ) {	    bool nextok =  board->contains(at+d);	    if ( node->isWord() && n && (!nextok || !board->tile(at+d)) )		noteChoice(tiles,n,d,blankvalues,blused);	    if ( nextok )		findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);	    // #### text()[1]...	}    } else {	if ( nletter[l.unicode()] || nletter[0] ) {	    int rc = rack->count();	    ulong msk = 1;	    for ( int x=0; x<rc; x++ ) {		if ( !(used&msk) ) {		    const Tile* t = rack->tileRef(x);		    if ( t->isBlank() || t->text() == l ) { // #### multi-char value()s			bool nextok =  board->contains(at+d);			tiles[n++] = t;			if ( t->isBlank() )			    blankvalues[blused++] = Tile(l,0);			if ( node->isWord() && (!nextok || !board->tile(at+d)) )			    noteChoice(tiles,n,d,blankvalues,blused);			used |= msk; // mark			nletter[t->text()[0].unicode()]--;			if ( nextok )			    findBest(at+d, d, node->jump(), used, nletter, tiles, n, blankvalues, blused);			n--;			nletter[t->text()[0].unicode()]++;			if ( t->isBlank() ) {			    // keep looking			    blused--;			    used &= ~msk; // unmark			} else {			    break;			}		    }		}		msk <<= 1;	    }	}	// #### text()[1]...    }    findBest(at, d, node->next(), used, nletter, tiles, n, blankvalues, blused);}void ComputerPlayer::noteChoice(const Tile** tiles, int n, const QPoint& d, const Tile* blankvalues, int blused){    int s = board->score(current, tiles, n, blankvalues, d, TRUE, 0);/*if (s>0 || current==QPoint(5,1)){QString st;for ( int i=0; i<n; i++ )    st += tiles[i]->text();qDebug("%d,%d: %s (%d) for %d",current.x(),current.y(),st.latin1(),n,s);}*/    if ( s > best_score ) {	int i;	for ( i=0; i<n; i++ )	    best[i] = tiles[i];	for ( i=0; i<blused; i++ )	    best_blankvalues[i] = blankvalues[i];	best_n = n;	best_blused = blused;	best_score = s;	best_dir = d;	best_start = current;    }}int TileItem::smallWidth(){    return tile_smallw;}int TileItem::smallHeight(){    return tile_smallh;}int TileItem::bigWidth(){    return tile_bigw;}int TileItem::bigHeight(){    return tile_bigh;}void TileItem::setState( State state ){    hide();    s = state;    show(); // ### use update() in Qt 3.0}void TileItem::setTile(const Tile& tile){    hide();    t = tile;    show(); // ### use update() in Qt 3.0}void TileItem::setBig(bool b){    big = b;}void TileItem::drawShape(QPainter& p){    static QFont *value_font=0;    static QFont *big_font=0;    static QFont *small_font=0;    if ( !value_font ) {	value_font = new QFont("helvetica",8);	if ( TileItem::bigWidth() < 20 ) {	    big_font = new QFont("helvetica",12);	    small_font = new QFont("helvetica",8);	} else {	    big_font = new QFont("smoothtimes",17);	    small_font = new QFont("smoothtimes",TileItem::smallWidth()*10/16);	}    }    QRect area((int)(x()),int(y()),width(),height());    p.setBrush(s == Floating ? yellow/*lightGray*/ : white);    p.drawRect(area);    if ( big ) {	p.setFont(*value_font);	QString n = QString::number(t.value());	int w = p.fontMetrics().width('1');	int h = p.fontMetrics().height();	w *= n.length();	QRect valuearea((int)(x())+width()-w-1,int(y())+height()-h,w,h);	p.drawText(valuearea,AlignCenter,n);	p.setFont(*big_font);	area = QRect(int(x()),int(y())+tile_btweak,width()-4,height()-1);    } else {	p.setFont(*small_font);	area = QRect(int(x())+1+tile_stweak,int(y())+1,width(),height()-3);    }    if ( t.value() == 0 )	p.setPen(darkGray);    p.drawText(area,AlignCenter,t.text().upper());}Board::Board(QPixmap bgshapes, int w, int h, QWidget* parent) :    QCanvasView(new QCanvas(bgshapes,w,h, TileItem::smallWidth(), TileItem::smallHeight()),		parent){    setFixedSize(w*TileItem::smallWidth(),h*TileItem::smallHeight());    grid = new TileItem*[w*h];    memset(grid,0,w*h*sizeof(TileItem*));    setFrameStyle(0);    setHScrollBarMode(AlwaysOff);    setVScrollBarMode(AlwaysOff);    current_rack = 0;    shown_n = 0;}Board::~Board(){    delete canvas();}QSize Board::sizeHint() const{    return QSize(canvas()->width(),canvas()->height());}void Board::writeConfig(Config& cfg){    unshowTurn(); // not simple to save this info    QStringList t;    int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();    for (int i=0; i<n; i++)	t.append( grid[i] ? grid[i]->tile().key() : QString(".") );    cfg.writeEntry("Board",t,';');}void Board::readConfig(Config& cfg){    clear();    QStringList t = cfg.readListEntry("Board",';');    int i=0;    int h=canvas()->tilesHorizontally();    for (QStringList::ConstIterator it=t.begin(); it!=t.end(); ++it) {	if ( *it != "." ) {	    QPoint p(i%h,i/h);	    setTile(p,Tile(*it));	}	i++;    }    canvas()->update();}void Board::clear(){    int n=canvas()->tilesHorizontally()*canvas()->tilesVertically();    for (int i=0; i<n; i++) {	delete grid[i];	grid[i]=0;    }}void Board::setCurrentRack(Rack* r){    turn_score = -1;    current_rack = r;}void Board::resetRack(){    unshowTurn();    canvas()->update();}void Board::contentsMousePressEvent(QMouseEvent* e){    dragstart = e->pos();}void Board::contentsMouseMoveEvent(QMouseEvent* e){    if ( current_rack && !current_rack->computerized() ) {	QPoint d = e->pos() - dragstart;	if ( d.x() <= 0 && d.y() <= 0 ) {	    // None	    resetRack();	} else {	    int n;	    QPoint start=boardPos(dragstart);	    QPoint end=boardPos(e->pos());	    QPoint diff=end-start;	    QPoint dir;	    if ( d.x() > d.y() ) {		n = diff.x()+1;		dir = QPoint(1,0);	    } else {		n = diff.y()+1;		dir = QPoint(0,1);	    }	    unshowTurn();	    // Subtract existing tiles from n	    QPoint t = start;	    for ( int i=n; i--; ) {		if ( contains(t) && tile(t) )		    n--;		t += dir;	    }	    // Move start back to real start	    while (contains(start-dir) && tile(start-dir))		start -= dir;	    scoreTurn(start, n, dir);	    showTurn();	}    }}void Board::finalizeTurn(){    int i=0;    QPoint at = shown_at;    while ( i<shown_n && contains(at) ) {	if ( item(at) && item(at)->state() == TileItem::Floating ) {	    current_rack->remove(item(at)->tile());	    setTileState(at,TileItem::Firm);	    i++;	}	at += shown_step;    }    canvas()->update();}void Board::unshowTurn(){    int i=0;    QPoint at = shown_at;    while ( i<shown_n && i<current_rack->count() && contains(at) ) {	if ( item(at) && item(at)->state() == TileItem::Floating ) {	    unsetTile(at);	    i++;	}	at += shown_step;    }}void Board::showTurn(){    unshowTurn();    QPoint at = shown_at;    int i=0;    while ( i<shown_n && i<current_rack->count() && contains(at) ) {	if ( !tile(at) ) {	    Tile t = current_rack->tile(i);	    setTile(at,t);	    setTileState(at,TileItem::Floating);	    i++;	}	at += shown_step;    }    canvas()->update();}int Board::bonussedValue(const QPoint& at, int base, int& all_mult) const{    int rule = rule_shape[idx(at)]-'0';    int effect = rule_effect[rule];    int mult = effect&Multiplier;    if ( effect & MultiplyAll ) {	all_mult *= mult;	return base;    } else {	return base * mult;    }}bool Board::isStart(const QPoint& at) const{    int rule = rule_shape[idx(at)]-'0';    int effect = rule_effect[rule];    return effect&Start;}bool Board::checkTurn(){    if ( current_rack->computerized() )	return TRUE; // computer doesn't cheat, and has already set blanks.    QPoint at = shown_at;    int n = shown_n;    QPoint d = shown_step;    const Tile* tiles[99];    Tile blankvalues[99];    if ( n > current_rack->count() )	n = current_rack->count();    QDialog check(this,0,TRUE);    (new QVBoxLayout(&check))->setAutoAdd(TRUE);    QHBox mw(&check);    new QLabel(tr("Blanks: "),&mw);    int bl=0;    QLineEdit* le[99];    for (int i=0; i<n; i++) {	tiles[i] = current_rack->tileRef(i);	if ( tiles[i]->isBlank() ) {	    QLineEdit *l = new QLineEdit(&mw);	    le[bl++] = l;	    l->setMaxLength(1);	    l->setFixedSize(l->minimumSizeHint());	}    }    QHBox btns(&check);    connect(new QPushButton(tr("OK"),&btns), SIGNAL(clicked()), &check, SLOT(accept()));    connect(new QPushButton(tr("Cancel"),&btns), SIGNAL(clicked()), &check, SLOT(reject()));    if ( bl ) {retry:	if ( !check.exec() ) {	    unshowTurn();	    canvas()->update();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -