Challenge 12 – Arrange non-overlapping ASCII rectangles in C++

Difficulty ![]() |
![]() |
This Challenge was proposed for the now defunct C/C++ programming list CWORLD in 1999.
The source code of the challenge has been updated to modern C++, but maintaining the essence of the challenge, which its original author wanted to transmit.
Date: 02-I-2001
Created by: David A. Capello
Challenge winner: Jose Luis de la Cruz
The program must draw 10 rectangles of a size that always varies between 1 to 10 in width and height (10×10). Now what happens, there is a problem, the rectangles want to take advantage of the space to the maximum and not put one on top of the other, so the task will be to generate the algorithm that looks for the best position for the rectangle to be placed (see the function “dibujar_rectangulo”).
Recomendations
You must carry out the function that seeks to position the rectangle on the screen so that it does not cover the others… if not, it will give you an error and the execution will end.
NOTE: the proposed function must always draw rectangles correctly, so the random proposal put forward by the author of the challenge is not valid, since it is random, and sometimes it works and other times it DOESN’T, so any other way that uses random or pseudo-random number generators will be incorrect.
Source Code
#include <iostream>
#include <cstdio>
#include <ctime>
using std::cout;
#define ANCHO 64
#define ALTO 38 /* height must always be even (since the lines are drawn two by two) */
char pantalla[ALTO][ANCHO]; /* access mode: screen[y][x] */
/* clear the entire screen buffer with 0 (zeros) */
void borrar_pantalla()
{
int x, y;
/* traverse from top to bottom */
for (y = 0; y < ALTO; y++)
/* traverse from left to right*/
for (x = 0; x < ANCHO; x++)
pantalla[y][x] = 0;
}
/* draws a rectangle of the given size at any position
on the screen, but it cannot cover areas already
occupied by other rectangles */
bool dibujar_rectangulo(int alto, int ancho)
{
int x, y, comienzox, comienzoy;
/* HERE YOU MUST COMPLETE: ****************************************/
/* You must carry out the function that seeks to position
* the rectangle on the screen so that it does not cover
* the others... if not, it will give you an error and
* the execution will end;
*
* NOTE: the function should always draw correctly, so
* this random proposal is not valid since it is random,
* and sometimes it works and other times it DOESN'T,
* so any other way that uses random or random or
* pseudo-random number generators will be wrong;
*/
comienzox = rand() % 32;
comienzoy = rand() % 20;
/* AND THIS IS WHERE YOUR WORK ENDS ********************************/
if ((comienzox < 0) || (comienzox + ancho > ANCHO) ||
(comienzoy < 0) || (comienzoy + alto > ALTO)) {
cout << "Sorry, you lost! You drew outside the screen limits\n";
return false;
}
/* draw it */
for (y = comienzoy; y < comienzoy + alto; y++)
for (x = comienzox; x < comienzox + ancho; x++) {
if (pantalla[y][x]) {
cout << "Sorry, you lost! Draw on top of another rectangle\n";
return false;
}
pantalla[y][x] = 1;
}
return true;
}
/* draw the full screen */
void dibujar_pantalla()
{
int x, y;
/* draw something to separate from the rest of the lines */
cout << "-------- [SCREEN] --------\n";
/* draw the screen (NOTE: 2 lines are drawn in a row
with the characters:
'█' (full), '▀' (top), '▄' (lower), ' ' (empty);
*/
for (y = 0; y < ALTO; y += 2) {
std::putc((unsigned char)'³', stdout);
/* draw two lines */
for (x = 0; x < ANCHO; x++) {
/* first line full */
if (pantalla[y][x]) {
/* second too */
if (pantalla[y + 1][x])
std::putc((unsigned char)219, stdout);
/* second empty */
else
std::putc((unsigned char)223, stdout);
}
/* first empty line */
else {
/* but second full */
if (pantalla[y + 1][x])
std::putc((unsigned char)220, stdout);
/* all empty */
else
std::putc((unsigned char)32, stdout);
}
}
/* jump to next line */
cout << "³\n";
}
/* draw another separator */
cout << "----------------------------\n";
}
int main()
{
int c;
/* start the random number generator */
srand((unsigned int)time(NULL));
/* clear screen */
borrar_pantalla();
/* draw ten rectangles */
for (c = 0; c < 10; c++)
if (dibujar_rectangulo((rand() % 10) + 1, (rand() % 10) + 1) == false)
return 1;
/* draw the entire screen */
dibujar_pantalla();
/* Since the above can cause problems, we will now test
the function with the limits he he he :-) */
borrar_pantalla();
for (c = 0; c < 10; c++)
dibujar_rectangulo(10, 10);
dibujar_pantalla();
cout << "YOU WON! If you liked this challenge remember to leave a comment\n";
cout << "in our guestbook www.theworldofchaos.com/contact/#guestbook and\n";
cout << "also thank the author of the challenge davidcapello.com\n\n";
cout << "Thank you\n";
return 0;
}
AND FINALLY I CAN ONLY SAY …. BEST OF LUCK AND MAY THE BEST CODE WIN….
If you liked this challenge remember to leave a comment in our guestbook