How put points in an 2D coordinate system radomly? - c++

i want this code can show:
1 2 3 .... 10
1 * *
2 #
.
. *
10 *
#include <iostream>
#include <iomanip>
#include <time.h>
int coordinates[1][10] = { 1,2,3,4, 5,6,7,8,9,10 };
for (int k = 0; k < 1; k++) {
for (int j = 0; j < 10; j++) {
cout << " " << coordinates[k][j];
}
cout << endl;
}
for (int r = 0; r < 1; r++) {
for (int s = 0; s < 10; s++) {
cout << coordinates[r][s] << endl;
}
}
return 0;
}
I want put sign# in position(3,2), LIKE THE ABOVE
and also put some points(*) into coordinate system randomly, and the points cannot be put them at 8 immediate neighbors of #position(3,2)

My suggestion is to make a 2d array of characters:
char board[MAX_ROWS][MAX_COLUMNS] = {0};
A better improvement is to use an extra column for the newline character:
char board[MAX_ROWS][MAX_COLUMNS + 1] = {0};
for (unsigned int i = 0U; i < MAX_ROWS; ++i)
{
board[i][MAX_COLUMNS] = '\n';
}
The extra column allows you to print the board with one statement:
std::cout << board << "\n";
If you want fancies, you can set up the output attributes before printing:
std::cout.width(3); // each cell is 3 wide
std::cout.fill(' '); // Pad each cell with spaces.
std::cout << board << "\n";
You can also add an extra column for displaying the row numbers and an extra row for display column numbers.
Edit 1: Setting a point
Setting a point is simple:
board[row][column] = '*'; // Set a point.
board[x][y] = ' '; // Erase a point.
Since the board is of type char, you can use different characters as points, such as '-', '+', 'M', etc.

Related

I have to do a program that do a square in c++ with incremental letter

Hello and thank you for coming here.
I have to do a program that will draw a number of square choosed by the user with incremental letter.
For example, if the user choose 4 square, it will return :
DDDDDDD
DCCCCCD
DCBBBCD
DCBABCD
DCBBBCD
DCCCCCD
DDDDDDD
At the time being, my code look like this ;
#include <iostream>
using namespace std;
int main()
{
int size;
int nbsquareletter;
cout << " How many square ?" << endl;
cin >> nbsquareletter;
size = nbsquareletter * 2 - 1;
char squareletter = 'a';
for (int row = 1; row <= size; ++row)
{
for (int col = 0; col <= size; ++col)
{
if (row < col) {
cout << (char)(squareletter + row - 1) << " ";
}
else if (row > col)
{
cout << (char)(squareletter + col) << " ";
}
/*
cout << col << " ";
cout << row << " ";
*/
}
cout << endl;
}
}
If you have any ideas to help me, don't hesitate, I'm struggling. it's been 3.5 hours. Thanks you for reading and have a good day !
Try to keep things simple. If you start write code before you have a clear idea of how to solve it you will end up with convoluted code. It will have bugs and fixing them will make the code even less simple.
Some simple considerartions:
The letter at position (i,j) is determined by the "distance" from the center. The distance is max(abs(i - i_0), abs(j - j_0).
The center is at (i,j) = (size-1,size-1) when we start to count at upper left corner (0,0).
The letters can be picked from an array std::string letters = "ABCDEFG...".
i and j are in the range [0,2*size-1)
Just writing this (and nothing more) down in code results in this:
#include <iostream>
#include <string>
void print_square(int size){
std::string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i_0 = size-1;
int j_0 = size-1;
for (int i=0;i< 2*size-1;++i){
for (int j=0;j< 2*size-1;++j) {
int index = std::max(std::abs(i-i_0),std::abs(j-j_0));
std::cout << letters[index];
}
std::cout << "\n";
}
}
int main() {
print_square(4);
}
Which produces output
DDDDDDD
DCCCCCD
DCBBBCD
DCBABCD
DCBBBCD
DCCCCCD
DDDDDDD
Your code cannot print the right output, because when row == col there is no output, and it misses the diagonal. I didnt look further than that.
Instead of fixing bugs in your code I decided to suggest you my own solution. Maybe some other answers will be related to bugs in your code.
On piece of paper I figured out 4 different formulas for 4 parts of a drawn picture, formulas computing what letter to take inside English alphabet. Afterwards I take this letter from array with alphabet.
Try it online!
#include <iostream>
int main() {
int n = 0;
std::cin >> n;
char const letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < 2 * n - 1; ++i) {
for (int j = 0; j < 2 * n - 1; ++j)
std::cout << letters[
i <= j && i + j < 2 * n - 1 ? n - i - 1 :
i <= j && i + j >= 2 * n - 1 ? j - n + 1 :
i > j && i + j < 2 * n - 1 ? n - j - 1 :
i > j && i + j >= 2 * n - 1 ? i - n + 1 : 25
];
std::cout << std::endl;
}
}
Input:
7
Output:
GGGGGGGGGGGGG
GFFFFFFFFFFFG
GFEEEEEEEEEFG
GFEDDDDDDDEFG
GFEDCCCCCDEFG
GFEDCBBBCDEFG
GFEDCBABCDEFG
GFEDCBBBCDEFG
GFEDCCCCCDEFG
GFEDDDDDDDEFG
GFEEEEEEEEEFG
GFFFFFFFFFFFG
GGGGGGGGGGGGG
Let's define some functions, to make the recurrence relation obvious.
std::vector<std::string> WrapInLetter(char letter, std::vector<std::string> lines)
{
for (auto & line : lines)
{
line.insert(line.begin(), letter);
line.insert(line.end(), letter);
}
std::size_t size = (lines.size() * 2) + 1;
std::string edge(size, letter); // A string formed of size copies of letter
lines.insert(lines.begin(), edge);
lines.insert(lines.end(), edge);
return lines;
}
std::vector<std::string> SquareLetter(char letter)
{
if (letter == 'A') return { "A" };
return WrapInLetter(letter, SquareLetter(letter - 1));
}
Now main just has to call that function and loop over the result.
int main()
{
std::cout << "How many square ?" << std::endl;
int size;
std::cin >> size;
for (auto line : SquareLetter('A' + size - 1))
{
std::cout << line << std::endl;
}
}

Checking if guessed string has a correct character at the wrong position

I want to generate a random string with letters a,b,c,d then let the user guess it.
My output should be which positions the user guessed correctly and how many letters the user guessed correctly but put them in the wrong position.
Current attempt:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
int main()
{
char lettres[4] =
{
'a',
'b',
'c',
'd'
};
char rString[4];
int i = 0;
srand(time(0));
while (i < 4)
{
int temp = rand() % 4;
rString[i] = lettres[temp];
i++;
}
int u = 0;
char t[4];
while (u < 10)
{
cout << "Enter your guess:\n ";
cin >> t;
for (int z = 0; z < 4; z++)
{
cout << rString[z] << ", "; //printing random string
}
cout << "\n";
int k;
int compteur = 0;
int t2[4];
int compteur2 = 0;
for (k = 0; k < 4; k++)
{
if (rString[k] == t[k]) //rString is my random string
{
t2[compteur2] = k;
compteur2++;
}
}
for (int y = 0; y < 4; y++)
for (int j = 0; j < 4; j++)
{
if (t[y] == rString[j] && y != j) //checking correct letters at wrong positions
{
compteur++;
t[y] = 'z'; //I put this line to avoid counting a letter twice
}
}
if (compteur2 == 4)
{
cout << "bravo\n";
u = 10;
} else
{
cout << "Positions with correct letters:\n ";
if (compteur2 == 0)
{
cout << "None";
cout << " ";
} else
for (int z = 0; z < compteur2; z++)
c out << t2[z] << ", ";
cout << " \n";
cout << "You have a total of " << compteur << " correct letters in wrong positions\n";
}
u++;
}
return 1;
}
Sample output:
Enter your guess:
abcd
b, a, b, a, //note this is my random string I made it print
Positions with correct letters:
None
You have a total of 1 correct letters in wrong positions
for example here I have 2 correct letters in the wrong position and I am getting 1 as an output
To clarify more about why I put t[y]='z'; if for example the random string was "accd" and my input was "cxyz" I would get that I have 2 correct letters at wrong positions, so I did that in attempt to fix it.
Any help on how to do this?
You should implement like this
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
int main() {
srand(time(0));
char lettres[4] = {'a','b','c','d'};
char rString[4];
int i = 0;
//making random string
while (i < 4) {
int temp = rand() % 4;
rString[i] = lettres[temp];
i++;
}
int u = 0;
char t[4];
while (u < 10) {
cout << "Enter your guess:\n ";
cin >> t;
//printing random string
for (int z = 0; z < 4; z++) {
cout << rString[z] << ", ";
}
cout << "\n";
int correctPositions = 0;
cout << "Correct Position Are:\n";
for (int z = 0; z < 4; z++) {
if (rString[z] == t[z]) {
cout << (z + 1) << ", ";
correctPositions++;
}
}
if (correctPositions == 4) {
cout << "\nBingo!" << "\nThat's Right!";
return 0;
}
if (correctPositions == 0) {
cout << "None";
}
cout << "\n";
//finding no of correct letters in wrong position:
int correctLetters = 0;
for (int i = 0; i < 4; i++) {
char c = lettres[i];
int randomCount = 0;
int guessCount = 0;
int letterInCorrectPos = 0;
for (int z = 0; z < 4; z++) {
if (rString[z] == c) {
randomCount++;
}
if (t[z] == c) {
guessCount++;
}
if (rString[z] == t[z] && t[z] == c)
letterInCorrectPos++;
}
correctLetters += min(guessCount, randomCount) - letterInCorrectPos;
}
cout << "No. of correct letters but in wrong position :" << correctLetters;
cout << "\n\n";
u++;
}
return 0;
}
Explaining Logic
1. Finding No. Of Correct Positions:
This is done by iterating with z = 0 -> z=4 over the rString and t if rString[z] is t[z] (the char at z are matching) then we just print the position!
2. Finding No. Of Correct Letters In Wrong Position
This part was little tricky to implement but here is the method I followed.
We have lettres[] array which is containing all the letters, right? We will now individual loop over each letter in the array and count the no. of occurrence in the rString and t, and store the respective counts in a randomCount and guessCount respectively.
Ex. let rString = "bdcc" and t = "abcd" so we have the following data:
'a': randomCount:0 guessCount:1 letterInCorrectPos: 0
'b': randomCount:1 guessCount:1 letterInCorrectPos: 0
'c': randomCount:2 guessCount:1 letterInCorrectPos: 1
'd': randomCount:1 guessCount:1 letterInCorrectPos: 0
This is the first part in the above loop you can see we have another variable letterInCorrectPos, this variable stores the no. of instances in the string where, the letter is at the same position in both the strings.
Figuring these three values we can calculate the no. of correct letter:
correctLetters = min(guessCount, randomCount)
the smaller value of guessCount or randomCount is chosen because we don't want repeated counting. (We can't have more correct letters than there are instances of that letter in another class).
Now by simple logic: correct letters in wrong place is (correct letters) - (correct letters in the correct place ).Hence,
correctLetters = min(guessCount, randomCount) - letterInCorrectPos;
Since we are iterating in a loop and we want to add correctLetters of each letter, we use this statement at the end of loop:
correctLetters += min(guessCount, randomCount) - letterInCorrectPos;
Hope this will explain the working.

Why does my function change values of an array twice in different places?

I have a function that changes the values of 4 array elements. It does that correctly but it also makes a copy of the 4 elements with an offset of (1, -10). I know it doesn't make much sense and I'm not sure how to explain it so I'll just show it.
Here is the code:
void PlayArea::addFigure(std::array<Vector2i, 4> figure, int color)
{
printCells();
std::cout << "\n\n";
for (int i = 0; i < 4; i++)
{
int x = figure[i].x;
int y = figure[i].y;
cell[x][y] = color;
}
printCells();
std::cout << "\n\n";
}
Notice the printCells function. What it does is print the elements of the array. The one before the for loop prints all zeros. The one after the for loop prints something like the one I described in the first paragraph. Here's a picture:
Edit:
The printCells method prints the contents of the 10 by 20 array cell, nothing more. I just added it for debugging. Here it is:
void PlayArea::printCells()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
std::cout << cell[j][i] << ", ";
}
std::cout << "\n";
}
}
The addFigure method is supposed to only add 4 elements to the cell array. I can't figure out how it stores 8.
Edit 2:
I tried replicating the problem on a separate project and this is the code:
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include <array>
#include <iostream>
#include <conio.h>
using namespace sf;
int cell[20][10] = { 0 };
void printCells()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
std::cout << cell[j][i] << ", ";
}
std::cout << "\n";
}
}
int main()
{
std::array<Vector2i, 4> figure;
figure[0].x = 1;
figure[0].y = 16;
figure[1].x = 1;
figure[1].y = 17;
figure[2].x = 1;
figure[2].y = 18;
figure[3].x = 1;
figure[3].y = 19;
printCells();
std::cout << "\n\n";
for (int i = 0; i < 4; i++)
{
cell[figure[i].x][figure[i].y] = 7;
}
//cell[1][19] = 7;
printCells();
std::cout << "\n\n";
_getch();
}
Every time I change a value of an element of the array it still changes two values 1 column and 10 rows apart. Here is an image:

How do I print out a 2-D array of the alphabet using a keyword?

So I was given the task to print out a 2-D array which is 5x5 having each letter of the alphabet in each of the locations of the array. I am supposed to use a keyword and print that in the rows of the 2-D array, then print out the rest of the letters of the alphabet. The letters should only be printed once in the whole array and 'Z' is excluded.
Not to good but this is what I have so far:
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
bool correct_keyword(char);
int main()
{
ifstream fin ("infile.txt");
char array[5][5];
char i, keyword;
bool correct;
cout << "Type in the key word: " << endl;
cin >> keyword;
correct_keyword(keyword);
for (int row = 0; row < 5; row++)
{
for (int col = 0; col < 5; col++)
{
keyword= array[row][col];
}
}
for (int row = 0; row < 5; row++)
{
for (int col = 0; col < 5; col++)
{
cout << keyword << " ";
}
cout << endl;
}
return 0;
}
bool correct_keyword(char keyword)
{
bool correct = false;
if (keyword != correct)
return true;
else
return 1;
}
If my keyword was "Fish" it would look something like this:
0 1 2 3 4
0 F I S H A
1 B C D E G
2 J K L M N
3 O P Q R T
4 U V W X Y
Any help would be appreciated!! Thank you very much!
If you have already declared the alphabet in the 2D array (5x5), let's say in char alphabet[5][5], you can print these values using nested for loops:
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
std::cout << alphabet[i][j] << std::endl;
The code will print all letters in new lines, if you need to print them as a 5x5 array, then this should work:
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
std::cout << alphabet[i][j] << " "; // separate letters with a space
}
std::cout << std::endl;
}
Why not use std::string to store you keyword? That provides .find() to check whether a character is included. You don't have to worry about a 2D array, all you need is your std::string and a counter and you can output the '\n' after every 5th character providing your output in a 5x5 grid.
How do you handle keywords with duplicate characters? Are they just considered invalid keywords? What about "wizard" would it likewise be an invalid keyword because it contains the excluded 'z' character? (I guess both would have to be, otherwise you would not be able to fill though 'y' in your 5x5 grid)
With that said, you could simply take your keyword as the first argument to your program and keep a counter of the number of characters output and do something simple like:
#include <iostream>
#include <string>
#define WIDTH 5
int main (int argc, char **argv) {
std::string s = argc > 1 ? argv[1] : "help";
size_t n = 0;
Now you need to check whether your keyword is valid, no duplicate characters and no 'z', e.g.
for (size_t i = 0; i < s.size() - 1; i++) /* check for duplicate chars */
if (s.find(s.at(i), i+1) != std::string::npos) {
std::cerr << "error: '" << s.at(i) << "' duplcate char.\n";
return 1;
}
if (s.find('z') != std::string::npos) { /* check for 'z' in input */
std::cerr << "error: input contains 'z'.\n";
return 1;
}
All that is left is outputting your keyword, followed by the remaining characters in the alphabet (minus 'z'). You can do that with two loops, e.g.
for (; n < s.size(); n++) { /* output keyword, keep n as count */
if (n && n % WIDTH == 0) /* impose WIDTH no. chars per-line */
std::cout << '\n';
std::cout << " " << s.at(n);
}
for (int i = 'a'; i < 'z'; i++) { /* output alphabet, skipping chars */
if (s.find((char)i) == std::string::npos) {
std::cout << " " << (char)i;
n++;
if (n && n % WIDTH == 0)
std::cout << '\n';
}
}
(note: the above uses lowercase characters, but you can simply change to uppercase if that is a requirement by swapping characters)
Putting it altogether, you could do:
#include <iostream>
#include <string>
#define WIDTH 5
int main (int argc, char **argv) {
std::string s = argc > 1 ? argv[1] : "help";
size_t n = 0;
for (size_t i = 0; i < s.size() - 1; i++) /* check for duplicate chars */
if (s.find(s.at(i), i+1) != std::string::npos) {
std::cerr << "error: '" << s.at(i) << "' duplcate char.\n";
return 1;
}
if (s.find('z') != std::string::npos) { /* check for 'z' in input */
std::cerr << "error: input contains 'z'.\n";
return 1;
}
for (; n < s.size(); n++) { /* output keyword, keep n as count */
if (n && n % WIDTH == 0) /* impose WIDTH no. chars per-line */
std::cout << '\n';
std::cout << " " << s.at(n);
}
for (int i = 'a'; i < 'z'; i++) { /* output alphabet, skipping chars */
if (s.find((char)i) == std::string::npos) {
std::cout << " " << (char)i;
n++;
if (n && n % WIDTH == 0)
std::cout << '\n';
}
}
}
(note: adding any surrounding Row or Column Headings, e.g. "0 1 2 3 4" is left to you)
Example Use/Output
With default "help" as keyword:
$ ./bin/alphabet
h e l p a
b c d f g
i j k m n
o q r s t
u v w x y
With "absent" as keyword:
$ ./bin/alphabet absent
a b s e n
t c d f g
h i j k l
m o p q r
u v w x y
Or an invalid keyword:
$ ./bin/alphabet hello
error: 'l' duplcate char.
You are free to use a 2D array, but it just seems like that would complicate input and storage of the keyword. Look things over and let me know if something like this would work and whether you have any further questions.

Programming puzzle - drawing an inverted triangle

The original question was to create a triangle out of hashes like this:
########
######
####
##
I decided to split the triangle in half and create half of each shape. Right now I have the code to create this shape:
####
###
##
#
code:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main () {
for (int row = 1; row <= 4; row++) {
for (int hashNum = 1; hashNum <= 5 - row; hashNum++) {
cout << "#";
}
cout << endl;
}
}
However, I cannot figure out how to create the other half of the shape. Does anyone have any ideas?
Here is a very step-by-step way to do it. Note there are more elegant ways to do this, namely recursion comes to mind.
#include <iostream>
void DrawTriangle(unsigned int rows)
{
// Loop over the rows
for(unsigned int spaces = 0; spaces < rows; ++spaces)
{
// Add the leading spaces
for(unsigned int i = 0; i < spaces; ++i)
{
std::cout << ' ';
}
// Add the hash characters
for(unsigned int j = 0; j < (rows - spaces)*2; ++j)
{
std::cout << '#';
}
// Add the trailing spaces
for(unsigned int i = 0; i < spaces; ++i)
{
std::cout << ' ';
}
// Add a newline to complete the row
std::cout << std::endl;
}
}
int main() {
DrawTriangle(4);
return 0;
}
Output
########
######
####
##
Sure: treat the blank area as a triangle of spaces, and double the width of your current triangle.
First of all I would consider the parameters of your problem. You are trying to draw a triangle of n rows of height with ascii chars. Considering that you take off one char on each side of the row on the next line, the minimum width of the base of your triangle is 2*(n-1)+1. For example, if you have n=3:
#####
###
#
Doing it this way your triangle shape will be better, with only one '#' at the bottom. After that the program is more straightforward. you can make something like this:
#include <iostream>
using namespace std;
void DrawInvTri(unsigned int nrows)
{
unsigned int ncols= (nrows-1)*2+1;
for (int i=0; i<nrows; i++)
{
// Write spaces before tri
for (unsigned int j=0; j<i; j++)
cout << " ";
// Write actual tri chars
for (unsigned int k=i; k<(ncols - i); k++)
cout << "#";
// Next line
cout << endl;
}
}
int main()
{
DrawInvTri(5);
DrawInvTri(3);
DrawInvTri(4);
return(0);
}