Problem is that I want 'o' , not to repeat... I tried to find but I failed!
Also explain me that how this happens. I am a new learning programmer!
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
using namespace std;
int main()
{
//all in-game variables here
string o = "o";
int oH = 0;
int oW = 0;
//variables ending point...
bool run = true;
bool frameShow = true;
char input;
int width = 53;
int height = 22;
string px[width][height];
while (run)
{
for (int xEmp=0; xEmp<height; xEmp++){
for (int yEmp=0; yEmp<width; yEmp++)
{
px[xEmp][yEmp]= " ";
}
if (frameShow)
{
clrscr(); // Must be at start
px[oH][oW] = o;
for (int x=0; x<height; x++)
{
for (int y=0; y<width; y++)
{
cout << px[x][y];
}
cout << "\n";
frameShow = false; // Must be at end
}
}
if (kbhit())
{
input = getch();
// Most Used ones are:
// char 119 for "w"
// char 97 for "a"
// char 115 for "s"
// char 100 for "d"
// char 32 for "space"
// char 27 for ESC
if (input == 119)
{
oH--;
frameShow = true;
}
else if (input == 115)
{
oH++;
frameShow = true;
}
else if (input == 97)
{
oW--;
frameShow = true;
}
else if (input == 100)
{
oW++;
frameShow = true;
}
else if (input == 27)
{
// Game exits...
// To terminate, use:
run = false;
}
if(oH > height)
{
oH = height;
}
else if(oH < 0)
{
oH = 0;
}
if(oW > width - 1)
{
oW = width - 1;
}
else if(oW < 0)
{
oW = 0;
}
}
}
}
// Output for confiming program termination
clrscr();
cout << "\n - Terminated! - \n";
return 0;
}
As a start, width and height use is being changed. px[width][height];, px[xEmp][yEmp], xEmp<height, yEmp<width. One time you use it as px[width][height];, then px[height][width];. keep your code coherent!
Also if(oH > height) { oH = height; } is wrong. subtract one from height.
This also probably doesn't do what you want:
for (int x=0; x<height; x++)
for (int y=0; y<width; y++)
{
cout << px[x][y];
}
cout << "\n";
Use brackets correctly, IF you don't know how to use them, put them ALWAYS!
Again, I think you're not using brackets correctly:
for (int xEmp=0; xEmp<height; xEmp++){
for (int yEmp=0; yEmp<width; yEmp++)
{
px[xEmp][yEmp]= " ";
}
... // do other things
}
I think you want to close it right away to set everything back to space and them do other works. As it is now, it will set one line back to spaces, print everything and run your code, and only after empty next line.
for (int xEmp=0; xEmp<height; xEmp++){
for (int yEmp=0; yEmp<width; yEmp++)
{
px[xEmp][yEmp]= " ";
}
}
... // do other things
Ps: clrscr() is a non-standard function, only works in Windows, I think, for Linux use system('clr');
Ps2: Why are you using std::string instead of char if you only store chars?
Related
This question already has answers here:
Output non-null terminated char array behaviours?
(3 answers)
Closed 3 months ago.
I am trying to make my own WORDLE game with C++. I have gotten to the point where I can check if a character is in the right spot but I do not know how to check if a letter is in the word but in a different place. This is what I have so far:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <cstdlib>
using namespace std;
string pickword();
string checkword(string ans, string word);
int main() {
string guess;
cout << "Hi welcome to WORDLE\n\n*Hit enter to start*";
cin.ignore();
string word = pickword();
cout << endl << word;
cout << "\nEnter a 5-letter word: ";
cin >> guess;
checkword(guess, word);
}
string pickword() {
srand((unsigned) time(NULL));
int random = 1 + (rand() % 1999);
string string;
ifstream ReadFile;
ReadFile.open("words.txt");
for (int i = 1; i <= random; i++) {
getline(ReadFile, string);
}
ReadFile.close();
return string;
}
string checkword(string ans, string word) {
char anslst[5];
char wrdlst[5];
for (int i = 0; i <= 4; i++) {
anslst[i] = ans[i];
wrdlst[i] = word[i];
}
//Green = \033[32m
//Red = \033[31m
//Yellow = \033[33m
for (int i = 0; i <= 4; i++) {
if (anslst[i] == wrdlst[i]) {
cout << "\033[32m" << anslst[i];
}
else if (anslst[i] != wrdlst[i]) {
cout << "\033[31m" << anslst[i];
}
}
return word;
}
the part relevent to the question is the bottom of checkword(). how can I see if the letters in the player's guess are in the the list containing the letters of the answer?
This main problem you're faced with isn't so much a question about C++, but instead an algorithmic question of "what to do with repeated letters?" For example, my understanding of the rules of Wordle are that a guess of "APPLE" when the answer was "PASTE", your first "P" should be yellow, but your second "P" should be grey. But if the answer had been "SPIPE", then "APPLE"'s second "P" should be yellow (because its first "P" is now green).
If we were to extend your C++ example with some of the programming choices you've already made, the central part of your checkword() might be written something like this:
EResult result[5];
for (int i = 0; i <= 4; i++) {
if (anslst[i] == wrdlst[i]) {
result[i] = GREEN;
}
else {
result[i] = GREY;
}
}
for (int i = 0; i <= 4; i++) {
if (result[i] != GREEN) {
bool searchingForYellow = true;
for (int j = 0; j <= 4 && searchingForYellow; j++) {
if (result[j] == GREY && anslst[i] == wrdlst[j]) {
result[j] = YELLOW;
searchingForYellow = false;
}
}
}
}
for (int i = 0; i <= 4; i++) {
if (result[i] == GREEN) {
cout << "\033[32m" << wrdlst[i];
}
else if (result[i] == YELLOW) {
cout << "\033[33m" << wrdlst[i];
}
else { // GREY
cout << "\033[31m" << wrdlst[i];
}
}
Notice that I've assumed you have an enumeration type named EResult with values GREEN or YELLOW or GREY (I haven't defined that type in my example code). You might need to study a bit about C++ enumerations if that is a new concept for you. Also consider using a "switch" statement instead of the condition at the end (but I'm not sure if you're familiar with "switch", so I wrote it this way for you instead). Also, consider using a "break" statement instead of the boolean variable (but again, I'm not sure how familiar you are with that programming element).
I'm pretty new to C++, and I'm trying to code a Wordle-like game, for 2 players using Visual Studio, to run in the windows cmd.
I want the user string input to be replaced with a '' or '*' character/symbol whilst it's being typed. I want to do this only using iostream, I have come across various solutions online, but none without importing any additional libraries (the solutions online usually use getch(), which needs an additional library)
My relevant (pretty bare) code is as follows:
#include <iostream>
using namespace std;
char a[5];
string str;
int main()
{
cout << "\nSet your Wordle first: ";
cin >> str;
for (int x = 0; x < 5; x++) {
a[x] = str[x];
}
return 0;
}
So I guess, as characters for 'str' are being typed, a '*' would be outputted on the windows console instead.
Any help or hints would be greatly appreciated, Thanks!
Note: Scroll down for updated code.
There is no way of achieving this without using external libraries. However, the closest you can achieve is this:
#include <iostream>
#include <Windows.h>
#include <conio.h>
// Positions the cursor 'home'. Visually clears the screen. Using this to avoid flickering
void cls()
{
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), COORD());
}
void input(std::string& str) // Asks the user for the word
{
int char_count = 0;
while (true)
{
cls();
std::cout << "Set your Wordle first: ";
for (int i = 0; i < char_count; i++)
{
std::cout << "*";
}
if (_kbhit())
{
char c = _getch();
if (c == '\r') // The character '\r' means enter
{
return;
}
char_count++;
str.push_back(c);
}
}
}
int main()
{
char a[5]{};
std::string str;
input(str);
for (int x = 0; x < 5; x++) // Constrain to 5 characters
{
if (x < str.size()) a[x] = str[x];
else break;
}
std::cout << std::endl; // Debug start
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
std::cout << a[i];
} // Debug end
}
This code works as you wanted. You may see the mouse flickering but as I said, there is no proper way to do this in C++. Also, this is not the complete wordle game, and the code between // Debug start and // Debug end is just for testing purposes.
Edit: I played around with it and fixed the blinking issue:
#include <iostream>
#include <Windows.h>
#include <conio.h>
int prev_char_count = 0;
// Positions the cursor 'home'. Visually clears the screen. Using this to avoid flickering
void cls()
{
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), COORD());
}
void input(std::string& str) // Asks the user for the word
{
int char_count = 0;
cls();
std::cout << "Set your Wordle first: ";
for (int i = 0; i < char_count; i++)
{
std::cout << "*";
}
while (true)
{
if (_kbhit())
{
cls();
std::cout << "Set your Wordle first: ";
char c = _getch();
if (c == '\r') // The character '\r' means enter
{
return;
}
char_count++;
str.push_back(c);
for (int i = 0; i < char_count; i++)
{
std::cout << "*";
}
}
}
}
int main()
{
char a[5]{};
std::string str;
input(str);
for (int x = 0; x < 5; x++) // Constrain to 5 characters
{
if (x < str.size()) a[x] = str[x];
else break;
}
std::cout << std::endl; // Debug start
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
std::cout << a[i];
} // Debug end
}
Hi I am attempting to create a chess board to reintroduce myself to c++. I am having trouble with adding a member function to my array that the chess board is located in.
I believe I am structuring the problem incorrectly.
.cpp file:
#include "spaces.h"
#include <iostream>
char board::spaceLetter() {
return letter;
}
char board::spaceNumber() {
return number;
}
string board::getColor(board a) {
if (a.color() == true) //Also an error but not a big deal
return "black";
else
return "white";
}
void board::printBoard(board a[][8]) {
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
if (a[i][j].color() == true) { //This is where my problem is
cout << "w";
}
else
cout << "b";
}
cout << endl;
}
}
Header .h
#pragma once
#include <iostream>
using namespace std;
class board {
private:
int boardSpace[8][8];
bool color;
char number;
char letter;
public:
board(){
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
if (((i + j) % 2) == 0)
color = true; //black space
else
color = false;
}
}
}
char spaceLetter();
char spaceNumber();
string getColor(board);
void printBoard(board a[][8]);
};
Thank you!
Welcome to SO.
if (a.color() == true) //Also an error but not a big deal
color is not a function. It is a member variable. Remove the () from color().
Same mistake here:
if (a[i][j].color() == true)
Try running the code here and see if it works for you: https://rextester.com/GRG48268
I'm new to C++ and I'm trying to figure out why I get two "*" symbols in my game board when I'm moving around. The game is supposed to be about avoiding the troll (#). But I am getting duplicate # and * symbols, and I can't figure out why. It seems that the problem is either in one of the for loops or in the posX or posY variables, which I found out by commenting out segments of the code:
#include <iostream>
#include <string>
using namespace std;
void ClearScreen()
{
cout << string(100, '\n');
}
main()
{
int size_arrx = 10;
int size_arry = 20;
int posX = 0;
int posY = 0;
int trollX = size_arrx - 1;
int trollY = size_arry - 1;
char a[size_arry][size_arrx];
bool Alive = true;
char player = '*';
char troll = '#';
while (Alive == true) {
ClearScreen();
for (int i = 0; i<size_arrx; i++)
{
for (int j = 0; j<size_arry; j++)
{
a[i][j] = 'x';
}
}
for (int i = 0; i<size_arrx; i++)
{
for (int j = 0; j<size_arry; j++)
{
a[posX][posY] = player;
a[trollX][trollY] = troll;
cout << a[i][j];
if (posX< 0) {
a[posX = 0][posY] = player;
cout << a[i][j];
}
else if (posY< 0) {
a[posX][posY = 0] = player;
cout << a[i][j];
}
else if (posY > size_arry - 1) {
a[posX][posY = size_arry - 1] = player;
cout << a[i][j];
}
else if (posX > size_arrx - 1) {
a[posX = size_arrx - 1][posY] = player;
cout << a[i][j];
}
}
cout << endl;
}
char dir;
cin >> dir;
if (dir == 'w') {
trollX++;
posX--;
}
if (dir == 's') {
trollX--;
posX++;
}
if (dir == 'd') {
trollY--;
posY++;
}
if (dir == 'a') {
trollY++;
posY--;
}
}
if ((trollX == posX) && (trollY == posY)) {
Alive == false;
}
}
The result looks like this. I only want one *. The * can move perfectly fine, but a duplicate * follows the original * but 11 X's away.
xxxxxxxxxx*xxxxxxxxx <---- This is a duplicate *
*xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx#
xxxxxxxxx#xxxxxxxxxx <---- This is a duplicate #
Thanks in advance if you can help me
for (int i=0;i<size_arrx;i++){
for (int j=0;j<size_arry;j++){
a[i][j]='x';
}
}
a[posX][posY]=player;
a[trollX][trollY]=troll;
for (int i=0;i<size_arrx;i++){
for (int j=0;j<size_arry;j++){
cout << a[i][j];
Using this code gave the same error. I'm interpreting this as a[i][j]='x' populates all positions of a[][] with X's. a[posX][posY]=player; overwrites the position of the player with an * (could be x 2 y 5 for example) and then the board gets printed by cout << a[i][j];. I don't understand how a duplicate symbol gets thrown in there.
Let's simplify your program.
Initialize the board outside of the while loop.
There should be no reason to keep initializing it:
for (unsigned int row = 0; row < size_arry; ++row)
{
std::fill(&a[row][0], &a[row][size_arrx], 'x'); // Fill a row.
}
Printing the board should be simple:
for (unsigned int row = 0; row < size_arry; ++row)
{
for (unsigned int column = 0; column < size_arrx; ++column)
{
cout << a[row][column];
}
cout << '\n';
}
Now the character logic.
Every character has a position, row and column, of where it is. To ease restoration, every character should have a previous position also.
struct Position
{
unsigned int row;
unsigned int column;
};
Sorry about that code, the fingers and keyboard are not cooperating.
To move a character to a valid new position, you have to restore the previous position:
unsigned int player_now_x;
unsigned int player_now_y;
unsigned int player_prev_x;
unsigned int player_prev_y;
//...
a[player_prev_y][player_prev_x] = 'x';
a[player_now_y][player_now_y] = player;
For processing single letter commands, a switch statement may be more readable:
// Update previous position.
player_prev_x = player_now_x;
player_prev_y = player_now_y;
switch (dir)
{
case 'd':
if (player_now_y < size_arry)
{
++player_now_y;
}
break;
case 's':
if (player_now_x < size_arrx)
{
++player_now_x;
}
break;
// ...
}
Simplifications.
You can print the board with one cout if you add an extra column. The ending column of each row (except the last) will have a line ending character, '\n'. The last column of the last row will have a termination character, '\0'.
struct Board
{
void set_player(const Position& pos, char player_token)
{
a[pos.x][pos.y] = player_token;
}
void move_player(const Position& new_position,
const Position& previous_position,
char player_token)
{
set_player(previous_position, 'x');
set_player(new_position, player_token);
}
void print()
{
std::cout << &a[0][0] << "\n";
}
Board()
{
for (unsigned int y = 0; y < size_arry; ++y)
{
std::fill(&a[y][0], &a[y][size_arrx], 'x');
a[y][size_arrx - 1] = '\n';
}
a[size_arry - 1][size_arrx - 1] = '\0';
}
};
//...
Board b;
Position player_now;
Position player_prev;
const char player_token = '*';
//...
switch (dir)
{
case 'd':
if (player_now.y < size_arry)
{
++player_now.y;
}
//...
}
b.move_player(player_now, player_previous, player_token);
Sorry again, for the above code fragment, it's the fingers typing out what they want.
I made a sudoku solver, but need to be able to take inputs in to set the puzzle before being solved. The input will be in a 1,2,,,,3,4 format where a space between 2 commas indicates a blank space (and obviously this will all be done row by row). I also have my code set up to use blank spots as 0s and would like to know how to read the input, parse each number into an int and also parse blanks as 0s.
As stated above, this is for C++ and is in Visual Studio Express 2013.
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "cstdlib"
#include "stdio.h"
#include "iostream"
#include "sstream"
using namespace std;
//find the first empty slot on the puzzle
bool FindEmptyCell(int puzzle[9][9], int &row, int &colm);
//check if the inserted number is a legal move
bool isLegal(int puzzle[9][9], int row, int colm, int num);
//being solving through backtracking
bool solve(int puzzle[9][9])
{
int row, colm; //establish rows and columns
//check if there are any empty slots
if (!FindEmptyCell(puzzle, row, colm))
{
return true; //puzzle is assumed solved
}
else
{
//start backtracking with the number 1
for (int i = 1; i<10; i++)
{
if (isLegal(puzzle, row, colm, i))
{
puzzle[row][colm] = i;
if (solve(puzzle) == true)
{
return true; //if there is no problem with the first number, move on
}
else
{
puzzle[row][colm] = 0;
}
}
}
}
return false; //start recursion to try next number
}
//check if the move is legal in the 3x3 square, needs the row and column of the square
bool CheckSquare(int puzzle[9][9], int sqRow, int sqColm, int chkNum)
{
for (int row = 0; row < 3; row++)
{
for (int colm = 0; colm < 3; colm++)
{
if (puzzle[row + sqRow][colm + sqColm] == chkNum)
{
return true; //the number is there and the move is illegal
}
}
}
return false; //the number is not there and the move is assumed legal
}
//check if the move is legal in the row
bool CheckRow(int puzzle[9][9], int row, int chkNum)
{
for (int colm = 0; colm <9; colm++)
{
if (puzzle[row][colm] == chkNum)
{
return true; //the number is there and the move is illegal
}
}
return false; // the number is not there and the move is assumed legal
}
//check if the move is legal in the column
bool CheckColm(int puzzle[9][9], int colm, int chkNum)
{
for (int row = 0; row <9; row++)
{
if (puzzle[row][colm] == chkNum)
{
return true; //the number is there and the move is illegal
}
}
return false; // the number is not there and the move is assumed legal
}
//definition of finding empty slot method
bool FindEmptyCell(int puzzle[9][9], int &row, int &colm)
{
for (colm = 0; colm < 9; colm++)
{
for (row = 0; row < 9; row++)
{
if (puzzle[row][colm] == 0)
{
return true;
}
}
}
return false;
}
//definition of is legal method
bool isLegal(int p[9][9], int r, int c, int cN)
{
if (CheckRow(p, r, cN) == false)
{
if (CheckColm(p, c, cN) == false)
{
if (CheckSquare(p, r - r % 3, c - c % 3, cN) == false) //use % to find the beginning row/column of the square
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
int main()
{
int puzzle[9][9];
string input;
for (int i=1; i <10; i++)
{
for (int j=1;j <10; j++)
{
cout << "Please insert the number for ["<< i << "," << j << "] (0 for no number)" << endl;
getline(cin, input);
int value = atoi(input.c_str());
puzzle[i-1][j-1] = value;
//get puzzle into correct format
}
}
if (solve(puzzle) == true)
{
string s;
cout << "Solving the puzzle..." << endl;
//print the puzzle to the screen
for (int i = 0; i<9;i++)
{
for (int j = 0; j<9; j++)
{
cout << puzzle[i][j] << ",";
}
cout << endl;
}
cout << "Press any button to escape";
getline(cin, s);
}
else
{
cout << "Can not solve the puzzle" << endl;
}
return 0;
}
Not sure why you need the code but here it is. Everything works properly, it just doesnt take input in the correct format currently.
As your numbers are only of 1 digit, you can:
int puzzle[9][9] = {};
for (int i = 1; i < 10; ++i)
{
cout << "Please input row #" << i << ": ";
getline(cin, input);
int j = 0;
const char *ptr = input.c_str();
while (*ptr)
{
if (isspace(*ptr)) ; // do nothing
else if (*ptr == ',') ++j; // new column
else puzzle[i - 1][j] = *ptr - '0';
++ptr;
}
}
To parse empty spaces as zerors, you need:
Initialize your matrix to zeros int puzzle[9][9] = { };
read the input line by line (each line representing a whole row)
use function strtok() to split (separate) the values using delimeter `','
for each separated value, trim it (i.e. remove spaces). Then, Use function atoi to covert it as an integer
Notice that you should check for empty separated string if (strlen(str))