Como mover mapa, 'char mapa[LINHAS][COLUNAS]={}'? [RESOLVIDO]

1. Como mover mapa, 'char mapa[LINHAS][COLUNAS]={}'? [RESOLVIDO]

Mistery
Cmistry

(usa Ubuntu)

Enviado em 03/02/2020 - 06:23h

Olá, monitores!
Ajude me a mover esse trem?
Objetivo é mover do lado esquerdo da tela para o lado direito começando pela 1 coluna do mapa, mas tudo que consigo é mover a primeira linha.
Se alguém consegui apenas mover o mapa já é de grande ajuda!


#include <stdio.h>
#define clear() printf("\33[H\33[2J");
//Move preenchendo com espaços em branco
int branco(int j){
int k;
for (k=60;k>=j;k--){
printf(" ");
}
}
#define COLUNAS 55
#define LINHAS 7
char mapa[LINHAS][COLUNAS+1]={
" ==== ________ ___________ ",
" _D _| |_______/ \\__I_I_____===__|_________|",
" |(_)--- | H\\________/ | | =|___ ___| ",
" / | | H | | | | ||_| |_|| ",
" | | | H |__--------------------| [___] | ",
" | ________|___H__/__|_____/[][]~\\_______| | ",
" |/ | |-----------I_____I [][] [] D |=======|__ ",
};
/* AQUI SERIA PARA MOVIMENTAR AS RODAS

"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__",
" |/-=|___|= || || || |_____/~\\___/ ", " \\_/ \\O=====O=====O=====O_/ \\_/ ", "__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__", " |/-=|___|=O=====O=====O=====O |_____/~\\___/ ", " \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",

"__/ =| o |=-O=====O=====O=====O \\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",

"__/ =| o |=-~O=====O=====O=====O\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ "
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",

"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__",
" |/-=|___|= O=====O=====O=====O|_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ ",

"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\_O=====O=====O=====O/ \\_/ ",

*/
int coluna_atual = 4, linha_atual = 4;
void desenhar(){
int linha=0;
while(linha<linha_atual)
printf("%s\n",mapa[linha++]);
printf("%.*s%s\n", coluna_atual, mapa[linha], mapa[linha]+coluna_atual+1);
while(++linha<LINHAS)
printf("%s\n",mapa[linha]);
}
#include <unistd.h>
int main(){
int i;for(i=0;i<60;i++){
clear();
usleep(50000);
branco(i);
desenhar();
}
printf("\n");
}


Aqui um exemplo movendo um carrinho, observe que ele já aparece totalmente na tela!


#include <stdio.h> #define clear() printf("\33[H\33[2J");
int branco(int j){ int k;
for (k=60;k>=j;k--){ printf(" ");
}
}
#include <unistd.h>
int main(){
int i;for(i=0;i<60;i++){ clear();
usleep(50000);
branco(i);
printf(" __@\n");
branco(i);
printf(" _`\\<,_\n");
branco(i);
printf(" (*)/ (*)\n");
}
}

Gif de um trem semelhante
https://raw.githubusercontent.com/jaseg/lolcat/master/sl.gif


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 06/02/2020 - 09:56h

Pensando depois, à noite, eu reparei que o programa que mostrei acima tem um problema. Ele assume que a largura da tela é maior do que a largura das linhas que formam a imagem a ser impressa, o que não é necessariamente verdade. Por exemplo, caso se optasse por um trem com vários vagões, em lugar de apenas a locomotiva, a largura total poderia ficar maior do que a do terminal, e a parte que considera que o trem já está saindo da tela pelo lado esquerdo imprimiria mais caracteres do que os que cabem na linha visível.

Pensei também numa melhoria, que é a de medir o tempo necessário para desenhar o quadro, e ajustar o tempo de pausa entre um quadro e outro a fim de manter constante (ou quase) a taxa de quadros por segundo ou a velocidade de deslocamento da figura.

A nova versão contempla os pontos acima.
// trem.c

// Compile o programa com “gcc -Wall -Werror -O2 -pedantic-errors trem.c -o trem -ltinfo”

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <term.h>
#include <time.h>

#define BODY_WIDTH 54
#define BODY_LINES 7
#define WHEELS_LINES 3
#define WHEEL_SETS 10

#define DEFAULT_TARGET_FRAME_RATE 29.97 // Quadros por segundo


char body[BODY_LINES][BODY_WIDTH+1]={
" ==== ________ ___________ ",
" _D _| |_______/ \\__I_I_____===__|_________| ",
" |(_)--- | H\\________/ | | =|___ ___| ",
" / | | H | | | | ||_| |_|| ",
" | | | H |__--------------------| [___] | ",
" | ________|___H__/__|_____/[][]~\\_______| | ",
" |/ | |-----------I_____I [][] [] D |=======|__ "
};

char wheels[WHEEL_SETS][WHEELS_LINES][BODY_WIDTH+1]={
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\_O=====O=====O=====O/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__O=====O=====O=====O \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= O=====O=====O=====O|_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~O=====O=====O=====O ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~O=====O=====O=====O ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~O=====O=====O=====O\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-O=====O=====O=====O~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|=O=====O=====O=====O |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ O=====O=====O=====O__/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\O=====O=====O=====O_/ \\_/ "
}
};


double my_gettime(void){
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
return t.tv_sec+1.0e-9*t.tv_nsec;
}



int main(int argc, char **argv){
// Vê se existe um valor válido de frame rate na linha de comando e, se
// existir, usa-o.
double target_frame_rate, frame_total_time;
char *eon=NULL;
if(
argc<2 ||
(target_frame_rate=strtod(argv[1], &eon))<=0 ||
*eon!='\0'
)
target_frame_rate=DEFAULT_TARGET_FRAME_RATE;
frame_total_time=1.0/target_frame_rate;

setupterm(NULL, STDOUT_FILENO, NULL);
putp(clear_screen);
putp(cursor_invisible);

const int first_line=10;
int wheel_set=0;

double start, remaining_delay;

for(int x=columns; x>=0; --x){
start=my_gettime();
for(int y=0; y<BODY_LINES; ++y){
putp(tparm(cursor_address, y+first_line, x));
printf("%.*s", columns-x, body[y]);
}
for(int y=0; y<WHEELS_LINES; ++y){
putp(tparm(cursor_address, y+first_line+BODY_LINES, x));
printf("%.*s", columns-x, wheels[wheel_set][y]);
}
wheel_set=(wheel_set+1)%WHEEL_SETS;
fflush(stdout);
remaining_delay=frame_total_time-(my_gettime()-start);
if(remaining_delay>0.0)
usleep(1000000*remaining_delay);
}

for(int width=BODY_WIDTH-1; width>=0; --width){
start=my_gettime();
for(int y=0; y<BODY_LINES; ++y){
putp(tparm(cursor_address, y+first_line, 0));
printf("%.*s", columns, body[y]+BODY_WIDTH-width);
}
for(int y=0; y<WHEELS_LINES; ++y){
putp(tparm(cursor_address, y+first_line+BODY_LINES, 0));
printf("%.*s", columns, wheels[wheel_set][y]+BODY_WIDTH-width);
}
wheel_set=(wheel_set+1)%WHEEL_SETS;
fflush(stdout);
remaining_delay=frame_total_time-(my_gettime()-start);
if(remaining_delay>0.0)
usleep(1000000*remaining_delay);
}

putp(cursor_normal);
putchar('\n');
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)

3. Re: Como mover mapa, 'char mapa[LINHAS][COLUNAS]={}'?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/02/2020 - 20:38h

Eu normalmente não gosto de entregar resposta de bandeja, mas acho que, neste caso, a melhor maneira de ensinar é mostrando como fazer.

Segue minha versão, com bastantes comentários.

// trem.c

// Compile o programa com “gcc -Wall -Werror -O2 -pedantic-errors trem.c -o trem -ltinfo”

#include <stdio.h>
#include <unistd.h>
#include <term.h>

#define BODY_WIDTH 54
#define BODY_LINES 7
#define WHEELS_LINES 3
#define WHEEL_SETS 10

#define FRAME_DELAY 25000 // Tempo em microsegundos.


char body[BODY_LINES][BODY_WIDTH+1]={
" ==== ________ ___________ ",
" _D _| |_______/ \\__I_I_____===__|_________| ",
" |(_)--- | H\\________/ | | =|___ ___| ",
" / | | H | | | | ||_| |_|| ",
" | | | H |__--------------------| [___] | ",
" | ________|___H__/__|_____/[][]~\\_______| | ",
" |/ | |-----------I_____I [][] [] D |=======|__ "
};

char wheels[WHEEL_SETS][WHEELS_LINES][BODY_WIDTH+1]={
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\_O=====O=====O=====O/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__O=====O=====O=====O \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= O=====O=====O=====O|_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~O=====O=====O=====O ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~O=====O=====O=====O ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~O=====O=====O=====O\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-O=====O=====O=====O~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|=O=====O=====O=====O |_____/~\\___/ ",
" \\_/ \\__/ \\__/ \\__/ \\__/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ O=====O=====O=====O__/ \\_/ "
},
{
"__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y________|__ ",
" |/-=|___|= || || || |_____/~\\___/ ",
" \\_/ \\O=====O=====O=====O_/ \\_/ "
}
};


int main(void){
setupterm(NULL, STDOUT_FILENO, NULL); // Inicializa o terminal.
putp(clear_screen); // Limpa a tela.
putp(cursor_invisible); // Desliga o cursor piscante.

const int first_line=10; // Linha em que o trem vai aparecer
int wheel_set=0; // Qual o conjunto de rodas a usar

// O trem começa fora da tela, à direita, e vai aparecendo aos poucos.
// Fazemos isso limitando a largura máxima de caracteres que serão
// impressos, por meio do modificador ".*" aplicado à conversão "%s" de
// printf().
for(int x=columns; x>=0; --x){ // “columns” é uma variável global
// de <term.h>, que diz a largura
// do terminal.
for(int y=0; y<BODY_LINES; ++y){
// Vai para a linha “y+first_line” e coluna “x”.
putp(tparm(cursor_address, y+first_line, x));

// “columns-x” é a limitação de quantos caracteres serão impressos
// (a largura máxima aplicada a "%s", graças à presença do modifi-
// cador ".*". Note que se o limite for maior do que a própria
// string, a string inteira é impressa, sem adicionar espaços à
// direita. Para apagar o pedaço que sobrou do quadro anterior,
// usam-se os espaços que foram colocados ao final de cada linha
// na definição do array “body”, que representa a carroceria do
// trem.
printf("%.*s", columns-x, body[y]);
}
for(int y=0; y<WHEELS_LINES; ++y){
// Vai para a linha “y+first_line+BODY_LINES” e coluna “x”.
putp(tparm(cursor_address, y+first_line+BODY_LINES, x));

// O conjunto de rodas desenhado a cada quadro é determinado pela
// variável wheel_set. Todos os conjuntos de rodas têm a mesma
// largura.
printf("%.*s", columns-x, wheels[wheel_set][y]);
}
wheel_set=(wheel_set+1)%WHEEL_SETS; // Avança para o próximo conjunto
// (ou volta ao primeiro deles).

fflush(stdout); // Desenha o quadro atual na tela.
usleep(FRAME_DELAY); // Pausa para ficar visível.
}

// Agora o trem sai da tela pelo lado esquerdo. Todos os quadros são de-
// senhados na primeira coluna mas, na hora de imprimir cada linha, eu
// começo a impressão a partir da coluna “BODY_WIDTH-width”, até que todo
// o trem suma da tela.
for(int width=BODY_WIDTH-1; width>=0; --width){
for(int y=0; y<BODY_LINES; ++y){
putp(tparm(cursor_address, y+first_line, 0));
printf("%s", body[y]+BODY_WIDTH-width);
}
for(int y=0; y<WHEELS_LINES; ++y){
putp(tparm(cursor_address, y+first_line+BODY_LINES, 0));
printf("%s", wheels[wheel_set][y]+BODY_WIDTH-width);
}
wheel_set=(wheel_set+1)%WHEEL_SETS;
fflush(stdout);
usleep(FRAME_DELAY);
}

putp(cursor_normal); // Restaura o cursor.
putchar('\n');
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


4. Será de profundo entendimento.

Mistery
Cmistry

(usa Ubuntu)

Enviado em 05/02/2020 - 23:22h


A vida muda diante a capacidade do cérebro desenvolver novas conexões sinápticas entre os terminais axiônimos, a parti da experiencia e do comportamento do individuo em meio ambiente inserido, determinados estímulos são aprendido e o desenvolvimento humano se torna um hábito continuo...
Sou muito seu fã, obrigado.
Será de profundo entendimento,