Commit ed7ec2e5 authored by Renan Alves de Morais Rocha's avatar Renan Alves de Morais Rocha
Browse files

adding comments

parent 645dc9fe
/**!
* @brief Sudoku interativo.
* @date Outubro, 10th
* @author Renan
*
*/
#ifndef ACTION_ACTION_MODE
#define ACTION_ACTION_MODE
/**!
* Função que verificar se o valor inserido é valido para posição.
* @param column coluna de inserção.
* @param row linha de inserção.
* @param number valor a ser inserido.
* @param cEmpty vetor com as informações das coordenadas anteriormente vazias.
* @param board tabuleiro de jogo.
* @return retorna a cor correspondente.
*/
short choiceColor(short column, short row, short number, std::vector <Coordinates> cEmpty,short board[SIZE][SIZE]){
row--;
column--;
int position=0;
int pRow = row/3;
int pColumn = column/3;
short boardTeste [SIZE][SIZE];
int position=0; /*!< Posição do vetor */
int pRow = row/3; /*!< Posição no quandrante das linhas */
int pColumn = column/3; /*!< Posição no quandrante das colunas */
short boardTeste [SIZE][SIZE]; /*!< Tabuleiro adaptado para comparação */
//Completar boardTeste com informações atuais do jogo.
for(int i=0; i<SIZE; i++){
for(int j=0; j<SIZE; j++){
if(board[i][j]<0){
......@@ -22,6 +38,7 @@ short choiceColor(short column, short row, short number, std::vector <Coordinate
}
}
//Verificar Coluna
for(int i=0; i<9; i++){
if(boardTeste[i][column]==number){
if(i!=row)
......@@ -29,6 +46,7 @@ short choiceColor(short column, short row, short number, std::vector <Coordinate
}
}
//Verificar Linha
for(int j=0; j<9; j++){
if(boardTeste[row][j]==number){
if(j!=column)
......@@ -36,6 +54,7 @@ short choiceColor(short column, short row, short number, std::vector <Coordinate
}
}
//Verificar Quadrante
for(int i=pRow*3; i<(pRow*3)+3; i++){
for(int j=pColumn*3; j<(pColumn*3)+3; j++){
if(boardTeste[i][j]==number){
......@@ -48,25 +67,35 @@ short choiceColor(short column, short row, short number, std::vector <Coordinate
return Color::BLUE;
}
//Remover valores no sudoku
/**!
* Função que remove o valor da posição requisitada.
* @param digitsLeft lista de valores restantes a serem inseridos.
* @param moves movimentos realizados.
* @param cEmpty vetor com as informações das coordenadas anteriormente vazias.
* @return retorna tuple de informações atualizadas.
*/
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::string> removeSudoku(std::vector <Coordinates> cEmpty,std::vector<Move> moves,std::vector<short> digitsLeft){
short row, column;
short row ;/*!< Posição da linha */
short column;/*!< Posição da coluna */
if (std::cin.peek() != '\n')
std::cin >> row >> column;
Coordinates c;
Coordinates c; /*!< Coordenadas temporarias */
//Verificar se a posição existe para que possa efetuar a remoção
for(int i=0; i<cEmpty.size(); i++){
c = cEmpty[i];
if(((c.row+1)==row) && ((c.column+1)==column)){
Move m;
Move m; /*!< Novo movimento realizado */
m.column = c.column;
m.row = c.row;
m.lastValue = cEmpty[i].value;
m.action = 'r';
cEmpty[i].value = 0;
moves.push_back(m);
if(m.lastValue>0)
digitsLeft[m.lastValue-1]++;
......@@ -78,53 +107,82 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::s
return std::make_tuple(cEmpty, moves, digitsLeft,"Invalid move");
}
//Inserir valores no sudoku
/**!
* Função que insere um valor na posição requisitada.
* @param digitsLeft lista de valores restantes a serem inseridos.
* @param moves movimentos realizados.
* @param cEmpty vetor com as informações das coordenadas anteriormente vazias.
* @param board tabuleiro de jogo.
* @return retorna tuple de informações atualizadas.
*/
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::string> insertSudoku(short board[SIZE][SIZE], std::vector <Coordinates> cEmpty,std::vector<Move> moves,std::vector<short> digitsLeft){
short row, column,number;
short row; /*!< Posição na linha */
short column; /*!< Posição na coluna */
short number; /*!< Número para ser inserido*/
if (std::cin.peek() != '\n')
std::cin >> row >> column >> number;
Coordinates c;
Coordinates c; /*!< Coordenadas temporarias */
std::string msg("Invalid insert");
for(int i=0; i<cEmpty.size(); i++){
c = cEmpty[i];
if(((c.row+1)==row) && ((c.column+1)==column)){
Move m;
m.column = c.column;
m.row = c.row;
m.lastValue = cEmpty[i].value;
m.action = 'p';
cEmpty[i].value = number;
cEmpty[i].color = choiceColor(column, row, number,cEmpty,board);
moves.push_back(m);
digitsLeft[number-1]--;
if(m.lastValue>0)
digitsLeft[m.lastValue-1]++;
if(cEmpty[i].color == Color::BLUE)
msg = "";
//Verificar se número é valido
if(number<10 && number>0){
//Verificar e inserir na posição.
for(int i=0; i<cEmpty.size(); i++){
c = cEmpty[i];
if(((c.row+1)==row) && ((c.column+1)==column)){
Move m; /*!< Novo movimento realizado */
m.column = c.column;
m.row = c.row;
m.lastValue = cEmpty[i].value;
m.action = 'p';
cEmpty[i].value = number;
cEmpty[i].color = choiceColor(column, row, number,cEmpty,board);
moves.push_back(m);
digitsLeft[number-1]--;
if(m.lastValue>0)
digitsLeft[m.lastValue-1]++;
if(cEmpty[i].color == Color::BLUE)
msg = "";
}
}
}
return std::make_tuple(cEmpty, moves, digitsLeft,msg);
}
//Voltar ação
/**!
* Função que cancela uma ação anterior.
* @param digitsLeft lista de valores restantes a serem inseridos.
* @param moves movimentos realizados.
* @param cEmpty vetor com as informações das coordenadas anteriormente vazias.
* @return retorna tuple de informações atualizadas.
*/
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::string> undoSudoku(std::vector <Coordinates> cEmpty,std::vector<Move> moves,std::vector<short> digitsLeft){
short size =moves.size();
short size =moves.size(); /*!< Tamanho da lista de movimentos */
//Verificar se tem jogadas anteriores.
if(size>0){
Move m = moves[size-1];
Coordinates c;
Move m = moves[size-1]; /*!< Último movimento realizado */
Coordinates c; /*!< Coordenadas da jogada */
//Remoção da jogada anterior.
for(int i=0; i<cEmpty.size(); i++){
c = cEmpty[i];
if(c.row==m.row && c.column==m.column){
if(cEmpty[i].value>0)
digitsLeft[cEmpty[i].value-1]++;
if(m.lastValue>0)
digitsLeft[m.lastValue-1]--;
cEmpty[i].value = m.lastValue;
moves.pop_back();
break;
......@@ -137,12 +195,20 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::s
}
}
//Verificar sudoku com resposta do jogador
/**!
* Função que verifica se o tabuleiro base e as posições respondidas são diferentes.
* @param coordinatesEmpty vetor com as informações das coordenadas anteriormente vazias.
* @param board1 tabuleiro de jogo
* @return retorna verdadeiro(se são diferentes) ou falso (se são iguais).
*/
bool is_Different(const short board1[SIZE][SIZE],std::vector <Coordinates> coordinatesEmpty){
Coordinates coord;
Coordinates coord; /*!< Informações da coordenada */
//Percorrer vetor de posições vazias
for(int i =0;i<coordinatesEmpty.size(); i++){
coord = coordinatesEmpty[i];
//Verificar se os valores são diferentes
if(-board1[coord.row][coord.column]!=coord.value)
return true;
......@@ -150,10 +216,16 @@ bool is_Different(const short board1[SIZE][SIZE],std::vector <Coordinates> coord
return false;
}
/**!
* Função que verifica se os valores das posições respondidas são corretas.
* @param cEmpty vetor com as informações das coordenadas anteriormente vazias.
* @param board tabuleiro de jogo
*/
void checked(const short board[SIZE][SIZE], std::vector <Coordinates> cEmpty,std::vector<Move> moves){
Coordinates c;
Coordinates c;/*!< Valor da coordenada */
//Percorrer o vetor e verificar informações
for(int i=0; i<cEmpty.size(); i++){
c = cEmpty[i];
......@@ -164,7 +236,7 @@ void checked(const short board[SIZE][SIZE], std::vector <Coordinates> cEmpty,std
}
//Mostar sudoku checado
printHeaderActionMode(moves);
printSudoku(board, cEmpty, moves);
......
/**!
* @brief Sudoku interativo.
* @date Outubro, 10th
* @author Renan
*
*/
#ifndef ACTION_MODE
#define ACTION_MODE
......@@ -7,26 +14,39 @@
#include "action_action_mode.h"
/**!
* Função que administra o Action Mode.
* @param interative tabuleiro interativo.
* @param digitsLeft lista com digitos restantes.
* @param moves movimentos realizados.
* @param cEmpty vetor com as informações das coordenadas anteriormente vazias.
* @param check checagens restantes.
* @return retorna lista com informações atualizadas.
*/
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int, bool> actionMode(Board interative, std::vector <Coordinates> cEmpty, std::vector<Move> moves, std::vector<short> digitsLeft,int check){
char action[2];// opção no action mode
std::string msg("");
char action[2];/*!< Opção no action mode */
std::string msg(""); /*!< Mensagens do action mode */
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::string> result;
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,std::string> result; /*!< Resultado das funções insertSudoku, removeSudoku e undoSudoku*/
//Verificar se o jogo foi resolvido.
while(is_Different(interative.board, cEmpty)){
//Printar o tabuleiro
printHeaderActionMode(moves);
printSudoku(interative.board, cEmpty, moves);
printDetailsActionMode(check, digitsLeft, msg);
printOptionsActionMode();
//Requisitar escolha do usuário
std::cin.get(action,2);
//Selecionar ação
switch(action[0]){
case 'p':
result= insertSudoku(interative.board,cEmpty,moves,digitsLeft);
cEmpty = std::get<0>(result);
moves = std::get<1>(result);
digitsLeft = std::get<2>(result);
......@@ -35,6 +55,7 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int, b
case 'r':
result= removeSudoku(cEmpty, moves,digitsLeft);
cEmpty = std::get<0>(result);
moves = std::get<1>(result);
digitsLeft = std::get<2>(result);
......@@ -42,10 +63,13 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int, b
break;
case 'c':
//Verificar se é possível a checagem
if(check > 0){
checked(interative.board, cEmpty, moves);
check--;
printDetailsActionMode(check, digitsLeft, "Checking done. Press enter to continue.");
std::cin.ignore();
msg ="Check done";
}else{
......@@ -55,6 +79,7 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int, b
case 'u':
result= undoSudoku(cEmpty, moves, digitsLeft);
cEmpty = std::get<0>(result);
moves = std::get<1>(result);
digitsLeft = std::get<2>(result);
......@@ -62,9 +87,13 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int, b
break;
default:
//Verificar se o enter foi precionado.
if (std::cin.peek() != '\n'){
//Limpar dados.
std::cin.clear();
std::cin.ignore();
return std::make_tuple(cEmpty, moves, digitsLeft, check, true);
}
msg ="Action unavailable";
......@@ -74,6 +103,7 @@ std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int, b
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
//Printar informações sobre conclusão do sudoku.
printHeaderActionMode(moves);
printSudoku(interative.board, cEmpty, moves);
printDetailsActionMode(check, digitsLeft, "Congratulation, you solved the puzzle! Press enter to continue.");
......
/**!
* @brief Sudoku interativo.
* @date Outubro, 10th
* @author Renan
*
*/
#ifndef PRINT_ACTION_MODE
#define PRINT_ACTION_MODE
//mostrar cabeçalho do action mode(Falta Concluir)
/**!
* Função que imprime o cabeçalho do Action Mode.
* @param moves movimentos realizados.
*/
void printHeaderActionMode(std::vector<Move> moves){
int size = moves.size();
std::cout<<Color::tcolor("|-------[ ACTION MODE ]-------|\n",Color::BLUE,Color::REGULAR);
//Verificar se há jogada anterior para adicionar marcador a posição
if(size>0){
short recoil = 5 + (2*(moves[size-1].column+1)) + 2*((moves[size-1].column)/3);
std::cout << std::setw(recoil)<< std::setfill (' ') << "v";
......@@ -13,6 +24,10 @@ void printHeaderActionMode(std::vector<Move> moves){
std::cout<<"\n";
}
/**!
* Função que imprime as opções do Action Mode.
*/
void printOptionsActionMode(){
std::cout<<Color::tcolor(
"\nCommands syntax:\n 'enter' (without typing anything) -> go back to previus menu.\n 'p' <row> <col> <number> + 'enter' -> place <number> on board at location (<row>, <col>).\n 'r' <row> <col> + 'enter' -> remove number on board at location (<row>, <col>).\n 'c' + 'enter' -> check which moves made are correct.\n 'u' + 'enter' -> undo lastplay.\n <row>, <col>, <number> must be in range [1,9].\n\n",
......@@ -21,12 +36,20 @@ void printOptionsActionMode(){
std::cout<<Color::tcolor("Enter command >",Color::YELLOW, Color::REGULAR);
}
/**!
* Função que imprime o cabeçalho do Action Mode.
* @param check número de checagens restantes.
* @param digitsLeft lista de números restantes.
* @param msg mensagem para usuário.
*/
void printDetailsActionMode(int check, std::vector <short> digitsLeft,std::string msg){
std::cout<<Color::tcolor(" Checks left: ["+std::to_string(check)+"]\n",Color::YELLOW, Color::REGULAR);
std::cout<<Color::tcolor(" Digits left: [",Color::YELLOW, Color::REGULAR);
//Imprimir lista de números restantes
for(int i=0; i<9;i++){
if(digitsLeft[i]>0)
std::cout<<Color::tcolor(" "+std::to_string(i+1),Color::YELLOW, Color::REGULAR);
else
......@@ -35,8 +58,7 @@ void printDetailsActionMode(int check, std::vector <short> digitsLeft,std::strin
std::cout<<Color::tcolor("]\n",Color::YELLOW, Color::REGULAR);
std::cout<<Color::tcolor(" MSG: [ "+msg+" ]\n",Color::YELLOW, Color::REGULAR);
}
#endif
\ No newline at end of file
#endif
/**!
* @brief Sudoku interativo.
* @date Outubro, 10th
* @author Renan
*
*/
#ifndef GET_SUDOKU
#define GET_SUDOKU
......@@ -23,51 +30,73 @@ struct Coordinates{
short color;
};
//Verificar posições vazias
/**!
* Função que cria vetor com as posições vazias do tabuleiro.
* @param board tabuleiro de jogo.
* @return retorna vetor com as posições vazias do tabuleiro.
*/
std::vector<Coordinates> startSudoku (const short board[SIZE][SIZE]){
std::vector<Coordinates> coordinatesEmpty;
for(int i=0; i<SIZE; i++){
for(int j=0; j<SIZE; j++){
if(board[i][j]<0){
Coordinates coordinates;
std::vector<Coordinates> coordinatesEmpty;/*!< Armazenamento das coordenadas vazias do tabuleiro*/
//Percorre tabuleiro
for(int i=0; i<SIZE; i++){
for(int j=0; j<SIZE; j++){
//Verifica se posição não ter valor certo
if(board[i][j]<0){
Coordinates coordinates; /*!< Nova coordenada para armazenamento*/
coordinates.row= i;
coordinates.column= j;
coordinates.value = board[i][j];
coordinates.color = Color::BLUE;
coordinatesEmpty.push_back(coordinates);
}
}
}
}
}
}
return coordinatesEmpty;
return coordinatesEmpty;
}
/**!
* Função que cria vetor com os número que faltam do tabuleiro.
* @param cEmpty lista com posições vazias.
* @return retorna vetor com os número que faltam do tabuleiro.
*/
std::vector<short> startDigitsLeft(std::vector<Coordinates> cEmpty){
std::vector<short> list{0,0,0,0,0,0,0,0,0};
std::vector<short> list{0,0,0,0,0,0,0,0,0}; /*!< Armazenamento dos número que faltam do tabuleiro.*/
int value; /*!< Valor pendente.*/
//Percorre o vetor e faz a contagem dos números faltantes
for(int i=0; i < cEmpty.size(); i++){
int value = -cEmpty[i].value;
list[value-1]++;
value = (-cEmpty[i].value) -1;
list[value]++;
}
return list;
}
/**!
* Função que lê um arquivo input.txt e gera tabuleiros Sudoku.
* @return retorna lista de tabuleiros.
*/
std::vector<Board> getSudokus() {
std::ifstream arq("./boards/input.txt");
Board b;
std::ifstream arq("./boards/input.txt"); /*!< Arquvio para leitura.*/
Board b; /*!< Tabuleiro para preenchimento.*/
std::vector<Board> boards;
std::vector<Board> boards; /*!< Lista de tabuleiros.*/
if (!arq){
std::cout<<"Problemas na abertura do arquivo\n";
std::cout<<"Problems opening the file.\n";
}else{
//Percorre o arquivo fazendo a leitura.
while (arq >> b.board[0][0]){
int k=1;
int k=1; /*!< Auxilar para percorrer o arquivo.*/
for(int i=0; i <SIZE; i++){
for(int j=k; j <SIZE; j++){
arq >> b.board[i][j];
......@@ -77,6 +106,8 @@ std::vector<Board> getSudokus() {
boards.push_back(b);
}
//fecha o arquivo
arq.close();
}
......
/**!
* @brief Sudoku interativo.
* @date Outubro, 10th
* @author Renan
*
*/
#include <iostream>
#include <iomanip>
#include <vector>
......@@ -9,91 +16,108 @@
#include "welcome.h"
/**!
* Função que controla o Main mode.
*/
int main(){
printWelcome();
int nSudoku=0;
short option=0; // Opções no main screen
short check=3; // numero de checagens restantes
bool playing; // verdadeiro enquanto se está jogando
std::string msg("");
int nSudoku=0; /*!< Posição do sudoku em utilização*/
short option=0; /*!< Opções no main screen*/
short check=3; /*!< Número de checagens restantes */
bool playing; /*!< Verdadeiro enquanto se está jogando */
std::string msg(""); /*!< Mensagem para o usuário*/
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int,bool> result;
std::tuple<std::vector <Coordinates>,std::vector<Move>,std::vector<short>,int,bool> result; /*!< Resultado da função actionMode*/
std::vector<Move> moves;
std::vector<Coordinates> coordinatesEmpty;
std::vector<Board> boards = getSudokus();
std::vector<Move> moves; /*!< Lista de movimentos anteriores.*/
std::vector<Coordinates> coordinatesEmpty; /*!< Lista de coordenadas vazias.*/
std::vector<Board> boards = getSudokus(); /*!< Lista de tabuleiros.*/
Board interative = boards[0];
Board interative = boards[0]; /*!< Tabuleiro interativo*/
// Inicar lista coordenadas vazias.
coordinatesEmpty =startSudoku(interative.board);
// Inicar lista de números não utilizados.
std::vector<short> digitsLeft =startDigitsLeft(coordinatesEmpty);
while(option!=3){
printHeaderMain();
printSudoku(interative.board, coordinatesEmpty, moves);
printMsg(msg);
printOptionsMain();
msg="";
std::cin >> option;
std::cin.get();
switch(option){
case 1:
result = actionMode(interative,coordinatesEmpty,moves, digitsLeft, check);
playing = std::get<4>(result);
if(playing){
coordinatesEmpty = std::get<0>(result);
moves = std::get<1>(result);
digitsLeft = std::get<2>(result);
check = std::get<3>(result);
}
break;
case 2:
if(playing){