explosive-c4/src/ 0000750 0001750 0001750 00000000000 14271774034 013225 5 ustar salvo salvo explosive-c4/src/board.cpp 0000640 0001750 0001750 00000015061 14271774034 015024 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#include
#include "board.h"
/**
* @brief Board::Board
*
* Default board: 6*7, red player starts
*/
Board::Board() {
init(6,7,PLAYER_RED);
}
Board::Board(int rows, int cols, player_t initial): QObject() {
init(rows,cols,initial);
}
/**
* @brief Board::Board
* @param initial: the player which starts
*
* Default 6*7 board
*/
Board::Board(player_t initial): QObject() {
init(6,7,initial);
}
/**
* @brief Board::Board
* @param rows
* @param cols
*
* Red player starts
*/
Board::Board(int rows, int cols): QObject() {
init(rows,cols,PLAYER_RED);
}
void Board::init(int rows, int cols, player_t initial) {
this->turn = initial;
this->rows = rows;
this->cols = cols;
this->size = rows*cols;
this->free_cells = rows*cols;
this->internal_board = new cell_t[size];
memset(internal_board, 0, size*sizeof(cell_t));
}
Board::~Board() {
delete this->internal_board;
}
/**
* @brief Board::get_size
* @param rows
* @param cols
*
* The pointed variables will be set with
* the values of rows and columns.
*/
void Board::get_size(int *rows, int *cols) {
*rows = this->rows;
*cols = this->cols;
}
/**
* @brief Board::free_slot
* @param col
* @return the position of the free
* slot in the column, or -1 if
* there is no free slot.
*/
int Board::free_slot(int col) {
int current_cell = col+((rows-1)*cols);
while (current_cell>=0) {
if (this->internal_board[current_cell] == CELL_EMPTY) {
int row = (current_cell-col)/cols;
return row;
} else {
current_cell -= cols;
}
}
return -1;
}
/**
* @brief Board::place
* @param col
* @param player
* @return
*
* Player makes a move and drops in column.
*
* Returns false if the player can't play there,
* can't play at all or if the game is over
*/
bool Board::place(int col, player_t player) {
if (turn != player || completed)
return false;
int row = this->free_slot(col);
if (row == -1) {
return false;
}
this->internal_board[col+row*cols] = (cell_t)player;
turn = (player_t)~turn;
emit changed(row,col);
if ((--this->free_cells) == 0)
completed = true;
check_winner(row,col);
return true;
}
/**
* @brief Board::winning_move
* Check if playing in row,col is a winning move.
*
* It doesn't check if it's a valid move.
*
*
* @param row
* @param col
* @return
*/
bool Board::winning_move(int row, int col, player_t player) {
//Store the previous value of the cell
cell_t previous = get_content(row,col);
this->internal_board[col+row*cols] = (cell_t)player;
cell_t current = (cell_t)player;
// diagonal
{
printf("Diagonal 1\n");
int count = 0;
for (int i = -3; i<=3; i++) {
if (get_content(row+i,col+i) == current)
count++;
else
count = 0;
printf("\tcount: %d\ti: %d\trow+i: %d\tcol+i: %d\tcontent: %d\n",count,i,row+i,col+i, get_content(row+i,col+i));
if (count == 4) {
goto win;
}
}
printf("End Diagonal 1\n");
}
{
printf("Diagonal 2\n");
int count = 0;
for (int i = -3; i<=3; i++) {
if (get_content(row+i,col-i) == current)
count++;
else
count = 0;
printf("\tcount: %d\ti: %d\trow+i: %d\tcol+i: %d\tcontent: %d\n",count,i,row+i,col+i, get_content(row+i,col+i));
if (count == 4) {
goto win;
}
}
printf("End Diagonal 2\n");
}
//Horizontal
{
printf("Horizontal\n");
int count = 0;
for (int i = col - 3; i <= col + 3; i++) {
if (get_content(row,i) == current)
count++;
else
count = 0;
printf("\tcount: %d\ti: %d\trow+i: %d\tcol+i: %d\tcontent: %d\n",count,i,row,col, get_content(row,i));
if (count == 4) {
goto win;
}
}
printf("End horizontal\n");
}
//Vertical
{
printf("Vertical\n");
int count = 0;
for (int i = row+1; i <=row+3; i++) {
if (get_content(i,col) == current)
count ++;
}
if (count == 3)
goto win;
printf("End vertical\n");
}
this->internal_board[col+row*cols] = previous;
return false;
win:
this->internal_board[col+row*cols] = previous;
printf("END GAME\n");
return true;
}
void Board::check_winner(int row, int col) {
player_t player = (player_t)get_content(row,col);
if (winning_move(row, col, player)) {
emit winner(player,row,col);
completed = true;
}
}
/**
* @brief Board::get_turn
* @return the player that needs to play
*/
player_t Board::get_turn() {
return turn;
}
/**
* @brief Board::dump
*
* Prints the board on stdout
*/
void Board::dump() {
for (int r=0;rinternal_board[r*cols+c]) {
case CELL_RED:
cell='X';
break;
case CELL_YELLOW:
cell='O';
break;
default:
cell= '.';
break;
}
printf ("%c ",cell);
}
printf("\n");
}
}
/**
* @brief Board::get_content
* @param row
* @param col
* @return the content for the specified cell.
*
* Boundary checks are performed so if the cell
* is out of the board, it is considered as an
* empty cell.
*/
cell_t Board::get_content(int row, int col) {
if (row= 0 && col >= 0)
return this->internal_board[col+row*cols];
else
return CELL_EMPTY;
}
explosive-c4/src/boardai.h 0000640 0001750 0001750 00000001747 14271774034 015011 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#ifndef BOARDAI_H
#define BOARDAI_H
#include "board.h"
class BoardAI: public Board {
public:
bool place(int col, player_t player) override;
private:
player_t aiplayer = PLAYER_YELLOW;
void airound();
};
#endif // BOARDAI_H
explosive-c4/src/explosive-c4_it_IT.ts 0000640 0001750 0001750 00000003643 14271774034 017216 0 ustar salvo salvo
MainUI
Two local players
Due giocatori locali
Play against computer
Gioca contro il computer
About
Informazioni su
←
←
↺
↺
explosive-c4
explosive-c4
<html><head/><body>
<p align="center"><span style=" font-weight:600;">explosive-c4</span></p>
<p>Released under AGPLv3</p>
<p>Contact: Salvo 'LtWorf' Tomaselli <a href="mailto:tiposchi@tiscali.it"><tiposchi@tiscali.it></a> </p>
<p><a href="https://github.com/ltworf/explosive-c4">https://github.com/ltworf/explosive-c4</a></p>
</body></html>
<html><head/><body>
<p align="center"><span style=" font-weight:600;">explosive-c4</span></p>
<p>Rilaciato sotto AGPLv3</p>
<p>Contatto: Salvo 'LtWorf' Tomaselli <a href="mailto:tiposchi@tiscali.it"><tiposchi@tiscali.it></a> </p>
<p><a href="https://github.com/ltworf/explosive-c4">https://github.com/ltworf/explosive-c4</a></p>
</body></html>
explosive-c4/src/mainui.h 0000640 0001750 0001750 00000002125 14271774034 014661 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#ifndef MAINUI_H
#define MAINUI_H
#include
#include "boardwidget.h"
namespace Ui {
class MainUI;
}
class MainUI : public QWidget
{
Q_OBJECT
public:
explicit MainUI(QWidget *parent = 0);
~MainUI();
private:
Ui::MainUI *ui;
BoardWidget * board_local = NULL;
BoardWidget * board_AI = NULL;
};
#endif // MAINUI_H
explosive-c4/src/mainui.ui 0000640 0001750 0001750 00000031226 14271774034 015053 0 ustar salvo salvo
MainUI
0
0
897
640
explosive-c4
* {
background-color: black;
color: white;
font: 24px;
}
QPushButton:disabled {
background-color: rgb(67, 67, 67);
border-color: rgb(67, 67, 67);
}
QPushButton {
color: black;
background-color: yellow;
border-width: 1px;
border-color: yellow;
border-style: solid;
border-radius: 10px;
min-width: 3em;
min-height: 30px;
padding: 6px;
}
QPushButton:pressed {
background-color: rgb(255, 193, 0);
border-color: rgb(255, 193, 0);
}
QPushButton:hover {
border-color: rgb(255, 193, 0);
}
QPushButton:default {
background-color: rgb(255, 255, 255);
}
3
6
3
6
-
QFrame::NoFrame
QFrame::Plain
0
0
0
0
0
-
Qt::Vertical
20
24
-
Qt::NoFocus
Two local players
false
false
-
Qt::NoFocus
Play against computer
false
false
-
Qt::Vertical
20
28
-
Qt::NoFocus
About
-
QFrame::NoFrame
QFrame::Plain
0
0
0
0
-
-
Qt::NoFocus
←
-
Qt::NoFocus
↺
-
QFrame::NoFrame
QFrame::Plain
0
0
0
0
-
-
Qt::NoFocus
←
-
Qt::NoFocus
↺
-
QFrame::NoFrame
QFrame::Plain
0
0
0
0
-
<html><head/><body>
<p align="center"><span style=" font-weight:600;">explosive-c4</span></p>
<p>Released under AGPLv3</p>
<p>Contact: Salvo 'LtWorf' Tomaselli <a href="mailto:tiposchi@tiscali.it"><tiposchi@tiscali.it></a> </p>
<p><a href="https://github.com/ltworf/explosive-c4">https://github.com/ltworf/explosive-c4</a></p>
</body></html>
true
true
-
Qt::Vertical
20
313
-
Qt::NoFocus
←
cmdLocalBack
clicked()
frmLocalGame
hide()
292
163
307
194
cmdLocalBack
clicked()
frmInitial
show()
270
163
137
247
cmdLocalGame
clicked()
frmInitial
hide()
131
69
192
110
cmdLocalGame
clicked()
frmLocalGame
show()
67
66
244
190
cmdLocalBackAI
clicked()
frmInitial
show()
243
433
200
258
cmdLocalBackAI
clicked()
frmAIGame
hide()
200
422
187
449
cmdIAGame
clicked()
frmAIGame
show()
135
148
178
371
cmdIAGame
clicked()
frmInitial
hide()
106
142
55
233
cmdAbout
clicked()
frmAbout
show()
66
599
531
319
cmdAbout
clicked()
frmInitial
hide()
66
599
66
319
cmdAboutBack
clicked()
frmAbout
hide()
496
167
559
319
cmdAboutBack
clicked()
frmInitial
show()
496
167
66
319
explosive-c4/src/explosive-c4.pro 0000644 0001750 0001750 00000004365 14271774034 016306 0 ustar salvo salvo # explosive-c4
# Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
# author Salvo "LtWorf" Tomaselli
#-------------------------------------------------
#
# Project created by QtCreator 2014-05-12T20:46:16
#
#-------------------------------------------------
QT += core widgets
TARGET = explosive-c4
TEMPLATE = app
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainui.cpp \
boardwidget.cpp \
boardai.cpp \
board.cpp
HEADERS += \
mainui.h \
boardwidget.h \
board.h \
boardai.h
FORMS += \
mainui.ui
CONFIG += mobility
MOBILITY =
CONFIG += c++11
TRANSLATIONS += \
explosive-c4_it_IT.ts
CONFIG += lrelease
CONFIG += embed_translations
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += \
android/AndroidManifest.xml
isEmpty(target.path) {
target.path = $${DESTDIR}/usr/games
export(target.path)
}
INSTALLS += target
launcher.files = extras/explosive-c4.desktop
launcher.path = $${DESTDIR}/usr/share/applications/
INSTALLS += launcher
icon.files = extras/high/explosive-c4.svg
icon.path = $${DESTDIR}/usr/share/icons/hicolor/128x128/apps/
INSTALLS += icon
icon_low.files = extras/low/explosive-c4.svg
icon_low.path = $${DESTDIR}/usr/share/icons/hicolor/48x48/apps/
INSTALLS += icon_low
manpage.files = extras/explosive-c4.6
manpage.path = $${DESTDIR}/usr/share/man/man6/
INSTALLS += manpage
export(INSTALLS)
explosive-c4/src/extras/ 0000750 0001750 0001750 00000000000 14271774034 014533 5 ustar salvo salvo explosive-c4/src/extras/high/ 0000750 0001750 0001750 00000000000 14271774034 015452 5 ustar salvo salvo explosive-c4/src/extras/high/explosive-c4.svg 0000640 0001750 0001750 00000003471 14271774034 020523 0 ustar salvo salvo
explosive-c4/src/extras/explosive-c4.desktop 0000640 0001750 0001750 00000000401 14271774034 020444 0 ustar salvo salvo [Desktop Entry]
Name=Explosive C4
Comment=Four in a row game
Comment[it]=Forza quattro
Exec=/usr/games/explosive-c4
Icon=explosive-c4
Terminal=false
Type=Application
Categories=Game;
Keywords=Games
X-Purism-FormFactor=Workstation;Mobile;
StartupNotify=true
explosive-c4/src/extras/explosive-c4.6 0000640 0001750 0001750 00000001617 14271774034 017152 0 ustar salvo salvo .TH "explosive-c4" 6 "Feb 20, 2022" "Four in a row game"
.SH "NAME"
explosive-c4 \(em Implementation of four in a row game.
.SH "SYNOPSIS"
.PP
\fBexplosive-c4\fR
.SH "DESCRIPTION"
.PP
This is a four in a row game implementation.
.br
Players place their red or yellow pieces in a vertical board, where they fall down.
.br
The goal is to place four pieces of the same colour in a row. Horizontally, vertically or diagonally.
.br
It is possible to play against the computer or against another person.
.SH "REPORTING BUGS"
.PP
Report all bugs here:
.SH "AUTHOR"
.PP
Written by Salvo "LtWorf" Tomaselli
.SH "COPYRIGHT"
.PP
Copyright © 2022 Salvo "LtWorf" Tomaselli. License AGPLv3: GNU Affero GPL version 3 .
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
explosive-c4/src/extras/low/ 0000750 0001750 0001750 00000000000 14271774034 015334 5 ustar salvo salvo explosive-c4/src/extras/low/explosive-c4.svg 0000640 0001750 0001750 00000002424 14271774034 020402 0 ustar salvo salvo
explosive-c4/src/boardai.cpp 0000640 0001750 0001750 00000016433 14271774034 015342 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#include
#include "boardai.h"
bool BoardAI::place(int col, player_t player) {
bool r = Board::place(col,player);
if (!r)
return false;
if (player != this->aiplayer) {
//Play AI round
airound();
}
return true;
}
void BoardAI::airound() {
player_t other_player = (player_t)~aiplayer;
//Do nothing if the game is already over
if (this->completed) {
return;
}
//Win in 1 move
{
for (int c=0; ccols; c++) {
int r = free_slot(c);
if (r != -1 && winning_move(r,c,aiplayer)) {
printf("Win in 1 move\n");
place(c,aiplayer);
return;
}
}
}
//Prevent win in 1 move
{
for (int c=0; ccols; c++) {
int r = free_slot(c);
if (r != -1 && winning_move(r,c,other_player)) {
printf("Prevent win in 1 move\n");
place(c,aiplayer);
return;
}
}
}
//Blacklist columns that would make the opponent win
QSet blacklist;
{
for (int c=0; c< this->cols; c++) {
int r = free_slot(c);
if (r == -1 || (r> 0 && winning_move(r-1,c,other_player)))
blacklist << c;
}
}
//Block lineup of 3 central pieces
//Horizontal
{
for (int row = 0; row< this->rows; row ++) {
for (int col = 1; col < this->cols-2; col++) {
if (
(
get_content(row,col-1) == CELL_EMPTY &&
get_content(row,col) == (cell_t)other_player &&
get_content(row,col+1) == (cell_t)other_player &&
get_content(row,col+2) == CELL_EMPTY
) ||
(
get_content(row,col-1) == CELL_EMPTY &&
get_content(row,col) == (cell_t)other_player &&
get_content(row,col+1) == CELL_EMPTY &&
get_content(row,col+2) == (cell_t)other_player
)) {
int r1 = free_slot(col-1);
int r2= free_slot(col+2);
int r3 = free_slot(col+1);
if (r1== row && !blacklist.contains(col-1)) {
printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
place(col-1, aiplayer);
return;
} else if (r2== row && !blacklist.contains(col+2)){
printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
place(col+2,aiplayer);
return;
} else if (r3== row&& !blacklist.contains(col+1)) {
printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
place(col+1,aiplayer);
return;
}
}
}
}
}
//Diagonal
{
for (int row = 1; row< this->rows-1; row ++) {
for (int col = 2; col < this->cols-2; col++) {
if (
(
get_content(row-1,col-1) == CELL_EMPTY &&
get_content(row,col) == (cell_t)other_player &&
get_content(row+1,col+1) == (cell_t)other_player &&
get_content(row+2,col+2) == CELL_EMPTY
) ||
(
get_content(row-1,col-1) == CELL_EMPTY &&
get_content(row,col) == (cell_t)other_player &&
get_content(row+1,col+1) == CELL_EMPTY &&
get_content(row+2,col+2) == (cell_t)other_player
)) {
int r1 = free_slot(col-1);
int r2= free_slot(col+2);
int r3 = free_slot(col+1);
if (r1== row-1&& !blacklist.contains(col-1)) {
place(col-1, aiplayer);
printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
return;
} else if (r2== row+2&& !blacklist.contains(col+2)){
place(col+2,aiplayer);
printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
return;
} else if (r3== row+1&& !blacklist.contains(col+1)) {
place(col+1,aiplayer);
printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
return;
}
}
}
}
}
{
for (int row = 1; row< this->rows-1; row ++) {
for (int col = 2; col < this->cols-2; col++) {
if (
(
get_content(row+1,col-1) == CELL_EMPTY &&
get_content(row,col) == (cell_t)other_player &&
get_content(row-1,col+1) == (cell_t)other_player &&
get_content(row-2,col+2) == CELL_EMPTY
) ||
(
get_content(row+1,col-1) == CELL_EMPTY &&
get_content(row,col) == (cell_t)other_player &&
get_content(row-1,col+1) == CELL_EMPTY &&
get_content(row-2,col+2) == (cell_t)other_player
)) {
int r1 = free_slot(col-1);
int r2= free_slot(col+2);
int r3 = free_slot(col+1);
if (r1== row+1&& !blacklist.contains(col-1)) {
place(col-1, aiplayer);
printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
return;
} else if (r2== row-2&& !blacklist.contains(col+2)){
place(col+2,aiplayer);
printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
return;
} else if (r3== row-1&& !blacklist.contains(col+1)) {
place(col+1,aiplayer);
printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
return;
}
}
}
}
}
//play randomly but blacklist some columns
{
printf("Randomly… %d: ",__LINE__);
int c;
while (true) {
c = rand() % this->cols;
printf("Selecting column %d\n",c);
if (blacklist.contains(c) && blacklist.size() < this->cols)
continue;
if (this->place(c,this->aiplayer))
break;
}
}
}
explosive-c4/src/boardwidget.h 0000640 0001750 0001750 00000003063 14271774034 015674 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#ifndef BOARDWIDGET_H
#define BOARDWIDGET_H
#include
#include "board.h"
typedef enum {
BOARD_WIDGET_LOCAL,
BOARD_WIDGET_AI,
BOARD_WIDGET_NETWORK,
} boardwidget_t;
class BoardWidget : public QWidget {
Q_OBJECT
public:
BoardWidget(boardwidget_t);
~BoardWidget();
virtual QSize sizeHint();
virtual QSize minimumSizeHint();
protected:
virtual void mousePressEvent(QMouseEvent *);
virtual void paintEvent(QPaintEvent *);
public slots:
void newgame();
private slots:
void changed(int row, int col);
void winner(player_t winner,int row, int col);
private:
Board * board = NULL;
int diameter;
int margin_x;
int margin_y;
int winner_row = -1;
int winner_col = -1;
boardwidget_t board_type;
void init();
};
#endif // BOARDWIDGET_H
explosive-c4/src/board.h 0000640 0001750 0001750 00000003366 14271774034 014476 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#ifndef BOARD_H
#define BOARD_H
#include
typedef enum {
PLAYER_RED=1,
PLAYER_YELLOW=~1,
} player_t;
typedef enum {
CELL_EMPTY=0,
CELL_RED=1,
CELL_YELLOW=~1,
} cell_t;
class Board : public QObject {
Q_OBJECT
public:
Board();
Board(int rows, int cols);
Board(int rows, int cols, player_t initial);
Board(player_t initial);
~Board();
void get_size(int *rows, int *cols);
virtual bool place(int col, player_t player);
cell_t get_content(int row, int col);
player_t get_turn();
void dump();
protected:
int rows;
int cols;
int size;
int free_cells;
cell_t *internal_board;
player_t turn = PLAYER_RED;
void check_winner(int row, int col);
bool winning_move(int row, int col, player_t player);
void init(int rows, int cols, player_t initial);
int free_slot(int col);
bool completed = false;
signals:
void winner(player_t,int row, int col);
void changed(int row, int col);
};
#endif // BOARD_H
explosive-c4/src/main.cpp 0000640 0001750 0001750 00000002743 14271774034 014664 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#include
#include
#include
#include "mainui.h"
#include "board.h"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
app.setApplicationName("explosive-c4");
app.setOrganizationDomain("explosive-c4");
app.setOrganizationName("explosive-c4");
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "explosive-c4_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
app.installTranslator(&translator);
break;
}
}
MainUI* foo = new MainUI();
foo->show();
return app.exec();
}
explosive-c4/src/mainui.cpp 0000640 0001750 0001750 00000003000 14271774034 015205 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#include "mainui.h"
#include "ui_mainui.h"
MainUI::MainUI(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainUI)
{
ui->setupUi(this);
resize(457, 640);
setWindowTitle("explosive-c4");
board_local = new BoardWidget(BOARD_WIDGET_LOCAL);
board_AI = new BoardWidget(BOARD_WIDGET_AI);
ui->frmLocalGame->setVisible(false);
ui->frmAIGame->setVisible(false);
ui->frmAbout->setVisible(false);
ui->frmLocalGame->layout()->addWidget(board_local);
ui->frmAIGame->layout()->addWidget(board_AI);
connect(ui->cmdNewLocalGame,SIGNAL(clicked()),board_local,SLOT(newgame()));
connect(ui->cmdNewAIGame,SIGNAL(clicked()),board_AI,SLOT(newgame()));
}
MainUI::~MainUI() {
delete ui;
delete board_AI;
delete board_local;
}
explosive-c4/src/boardwidget.cpp 0000644 0001750 0001750 00000014602 14271774034 016234 0 ustar salvo salvo /*
explosive-c4
Copyright (C) 2014-2022 Salvo "LtWorf" Tomaselli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
author Salvo "LtWorf" Tomaselli
*/
#include
#include
#include
#include
#include
#include
#include
#include "boardwidget.h"
#include "boardai.h"
// map cell type to pen and brush color
static QMap > cell_color;
static const QColor board_color0 = QColor("#434343");
static const QColor board_color1 = QColor("#333333");
static const QColor win_color0 = QColor("#f3f3f3");
static const QColor win_color1 = QColor("#030303");
static QLinearGradient board_gradient, ring_gradient;
static QLinearGradient win_gradient, ring_win_gradient;
BoardWidget::BoardWidget(boardwidget_t board_type) {
QWidget();
this->board_type = board_type;
// initialize color table and gradients
if (cell_color.empty()) {
cell_color[CELL_RED] = qMakePair(QColor("#ff4500"), Qt::red);
cell_color[CELL_YELLOW] = qMakePair(Qt::yellow, QColor("#ffd700"));
cell_color[CELL_EMPTY] = qMakePair(Qt::white, Qt::white);
board_gradient.setStart(0.73, 0.92);
board_gradient.setFinalStop(0.4, 0.6);
board_gradient.setCoordinateMode(QGradient::ObjectMode);
board_gradient.setColorAt(0, board_color0);
board_gradient.setColorAt(1, board_color1);
ring_gradient = board_gradient;
ring_gradient.setColorAt(0, board_color1);
ring_gradient.setColorAt(1, board_color0);
win_gradient = board_gradient;
win_gradient.setColorAt(0, win_color0);
win_gradient.setColorAt(1, win_color1);
ring_win_gradient = win_gradient;
ring_win_gradient.setColorAt(0, win_color1);
ring_win_gradient.setColorAt(1, win_color0);
}
init();
}
void BoardWidget::init() {
if (board!=NULL) {
delete board;
}
switch (board_type) {
case BOARD_WIDGET_LOCAL:
board = new Board();
break;
case BOARD_WIDGET_AI:
board = new BoardAI();
break;
case BOARD_WIDGET_NETWORK:
//TODO something about this
break;
}
connect(board,
SIGNAL(changed(int,int)),
this,
SLOT(changed(int,int))
);
connect(board,
SIGNAL(winner(player_t,int, int)),
this,
SLOT(winner(player_t, int, int))
);
QSize size = this->size();
update(0,0,size.width(),size.height());
}
BoardWidget::~BoardWidget() {
delete board;
}
void BoardWidget::winner(player_t winner, int row, int col) {
winner_row = row;
winner_col = col;
}
void BoardWidget::newgame() {
winner_col = winner_row = -1;
init();
}
void BoardWidget::paintEvent(QPaintEvent * p) {
QWidget::paintEvent(p);
QPainter painter(this);
QSize size = this->size();
int rows;
int cols;
board->get_size(&rows,&cols);
int w_max = size.width() / cols;
int h_max = size.height() / rows;
diameter = w_max < h_max ? w_max : h_max;
// we want the hole to take ~3/4th of a cell, so the offset
// for the circle within the cell is 1/8 of the cell width.
// we want at least 1px anyway
int hole_offset = diameter < 8 ? 1 : diameter/8;
// the hole ring is half the hole_offset.
// it's OK if this is 0, which only happens for very small boards
// (in this case there will be no ring)
int ring_offset = hole_offset/2;
// ensure that the hole_offset is even (rounds down)
if (ring_offset > 0)
hole_offset = ring_offset*2;
// the hole diameter will be what's left from the cell diameter
// given symmetric offset
int hole_diam = diameter - 2*hole_offset;
int ring_diam = diameter - 2*ring_offset;
int grid_width = diameter*cols;
int grid_height = diameter*rows;
margin_x = (size.width() - grid_width )/2;
margin_y = (size.height() - grid_height)/2;
painter.fillRect(0, 0, size.width(), size.height(), Qt::black);
painter.fillRect(margin_x, margin_y, grid_width, grid_height, board_gradient);
painter.setRenderHint(QPainter::Antialiasing, true);
for (int r=0; rget_content(r,c);
painter.setPen(QPen(cell_color[cell].first, ring_offset));
painter.setBrush(QBrush(cell_color[cell].second, Qt::SolidPattern));
painter.drawEllipse(x_corner + hole_offset, y_corner + hole_offset, hole_diam, hole_diam);
if (ring_offset > 0) {
painter.setPen( QPen((winner_pos ? ring_win_gradient : ring_gradient), ring_offset) );
painter.setBrush( Qt::NoBrush );
painter.drawEllipse(x_corner + ring_offset, y_corner + ring_offset, ring_diam, ring_diam);
}
}
}
}
void BoardWidget::changed(int row, int col) {
update(margin_x + col*diameter, margin_y + row*diameter, diameter, diameter);
}
void BoardWidget::mousePressEvent(QMouseEvent *ev) {
QWidget::mousePressEvent(ev);
int column = (ev->position().x() - margin_x) / diameter;
int rows;
int cols;
board->get_size(&rows,&cols);
if (column >= cols)
return;
player_t t = board->get_turn();
board->place(column,t);
}
QSize BoardWidget::minimumSizeHint() {
int rows;
int cols;
board->get_size(&rows,&cols);
return QSize(cols*30,rows*30);
}
QSize BoardWidget::sizeHint() {
int rows;
int cols;
board->get_size(&rows,&cols);
return QSize(cols*diameter,rows*diameter);
}
explosive-c4/src/android/ 0000750 0001750 0001750 00000000000 14271774034 014645 5 ustar salvo salvo explosive-c4/src/android/AndroidManifest.xml 0000640 0001750 0001750 00000006751 14271774034 020450 0 ustar salvo salvo
explosive-c4/src/android/res/ 0000750 0001750 0001750 00000000000 14271774034 015436 5 ustar salvo salvo explosive-c4/src/android/res/drawable-hdpi/ 0000750 0001750 0001750 00000000000 14271774034 020141 5 ustar salvo salvo explosive-c4/src/android/res/drawable-hdpi/icon.png 0000640 0001750 0001750 00000001730 14271774034 021601 0 ustar salvo salvo PNG
IHDR >a sBIT|d pHYs + zIDATxA0T~}mCrpW 428*!6q/OϬ|\6G墭B
mnμ
1Jx4!7Jt@-6R
cP%r.ƑMGC
0y ` s09`N ~n8t s09Th! U?R
HojzhC@%6S
| ̊V\4({
W^4)yf42 & ` s0 & @C6p k|M5B>F `3
pd0|4D ` s096`0|4B>F `S
\hhA>g0 s09`δ|cᘣ)WK
b3XD6?ok6?nMT2@ Q}3u,;ZOپ,ԛH]|_#6@uYC> %`0I`֟9Z3Gk- HP}_}oPeU&k6Az *dLc5DY(LdDm$ a2VA> ` s,
'Wj'M]>dSl>}'m>dX`6q4 Q s09|f(C0 ` s09|f(C0X`6|f(Gl>c'|f(.`|2
DA`A` s{Birv IENDB` explosive-c4/src/android/res/drawable-mdpi/ 0000750 0001750 0001750 00000000000 14271774034 020146 5 ustar salvo salvo explosive-c4/src/android/res/drawable-mdpi/icon.png 0000640 0001750 0001750 00000002055 14271774034 021607 0 ustar salvo salvo PNG
IHDR @ @ iq sBIT|d pHYs + IDATxXu0`
9 0s!G) E5CҌGh4s?,β OW>F#8Κs_(~ s}" Ȳ'Irg17q>Y1*(z6%U(0 tX IA4J9TI胃>;sM@"˲7U]9@g`c2oqg@0HQ|)
+/F&_ gʘy냃;`<s
]%82Ur]9@1c, 2+%6`%51{MӕW_X=X=tX= O&