Data de publicació: Dec 04, 2011 7:45:32 PM
You need the next folder structure.
Note that this program uses ncurses library.
Just make for compiling.
[ikasten@ikasten cumagic_mouse]$ tree
.
├── cal_cumagic.c
├── cumagic
├── cumagic.c
├── imp_cumagic.c
├── include
│ ├── cal_cumagic.h
│ ├── cumagic.h
│ ├── imp_cumagic.h
│ └── rat_cumagic.h
├── makefile
└── rat_cumagic.c
1 directory, 10 files
[ikasten@ikasten cumagic_mouse]$ make
gcc -c cumagic.c
gcc -c cal_cumagic.c
gcc -c imp_cumagic.c
gcc -c rat_cumagic.c
gcc -o cumagic cumagic.o cal_cumagic.o imp_cumagic.o rat_cumagic.o -lncurses
[ikasten@ikasten cumagic_mouse]$
Makefile
D_INCLUDE = include
PROGRAMES = cumagic.o cal_cumagic.o imp_cumagic.o rat_cumagic.o
cumagic : $(PROGRAMES)
gcc -o cumagic $(PROGRAMES) -lncurses
cumagic.o : cumagic.c $(D_INCLUDE)/cumagic.h
gcc -c $<
cal_cumagic.o : cal_cumagic.c $(D_INCLUDE)/cal_cumagic.h $(D_INCLUDE)/cumagic.h
gcc -c $<
imp_cumagic.o : imp_cumagic.c $(D_INCLUDE)/imp_cumagic.h $(D_INCLUDE)/cumagic.h
gcc -c $<
rat_cumagic.o : rat_cumagic.c $(D_INCLUDE)/rat_cumagic.h $(D_INCLUDE)/cumagic.h
gcc -c $<
.PHONY : netejar
net :
$(RM) *.o
cumagic.h
#define MAX 15
#define AMP_C 5
#define ALT_C 2
#define CUADRE_A 0
#define CUADRE_B 1
#define CASELLA_VALOR 1
#define CASELLA_ZERO 2
#ifndef CU_H
#define CU_H
#include <ncurses.h>
typedef struct{
int x;
int y;
}t_coord;
typedef struct {
int num;
t_coord pos_num;
t_coord pos_cas;
int lx;
int ly;
} t_casella;
typedef struct{
t_casella cu[MAX][MAX];
t_casella sumX[MAX];
t_casella sumY[MAX];
t_casella DiaA;
t_casella DiaB;
t_coord pos_erx;
int lx;
int ly;
} t_enreixat;
t_enreixat cA,cB;
#endif
int inicialitzar();
int finalitzar();
int menu_principal(int *n,int *op);
int assigna_valor();
int seleccionar_valor(t_enreixat **e,int *fila,int *columna);
int insertar_valor(t_enreixat *e_orig,t_enreixat *e_dest,int f_orig,int c_orig,int f_dest,int c_dest);
cal_cumagic.h
//funcions privades del modul
int SumaX(int n);
int SumaY(int n);
int SumaDiaA(int n);
int SumaDiaB(int n);
int cureset(int n);
//funcions públiques
int cal_cumagic(int n,int p);
int cal_suma(int n);
int cal_emplenar_cB(int n);
int pos_act;
imp_cumagic.h
#define ENREIXAT 1
#define NOMBRES 2
#define ENR_SEL 3
#define NOM_SEL 4
//funcions privades
void rep_car(int nc,chtype c);
void lg(int y,int x, int l, chtype Cfirst, chtype C2,int nC2, chtype C3, chtype Clast);
//funcions públiques
int imp_init_w();
void imp_fi_w();
int imp_cumagic(int n,t_enreixat *e);
void imp_dib_enreixat(int y, int x, int costat);
void imp_ubica_posyx(int y, int x,int n,t_enreixat *e);
void imp_cuadre(int y,int x,int alt,int amp);
int imp_sel_fc(int fila,int columna,t_enreixat *e,int *valor);
int imp_desel_fc(int fila,int columna,t_enreixat *e);
int imp_init_color();
rat_cumagic.h
#include "cumagic.h"
//funcions publiques
int rat_act_event_mouse();
int rat_yx_fc(t_enreixat *e,int n,int y, int x, int *fila, int *columna);
cumagic.c
#include "include/cumagic.h"
MEVENT pnt;
int n;
int main(void)
{
int op,valor,quit=0,key;
int fil,col,fil_orig,col_orig,fil_dest,col_dest;
int val_sel=-1;
t_enreixat *erx_orig,*erx_dest,*erx;
inicialitzar();
menu_principal(&n,&op);
//Dibuixa enreixat principal i carrega les estructures amb els valors pertinents
imp_dib_enreixat(10,5,n,&cA);
imp_ubica_posyx(10,5,n,&cA);
//case principal
switch(op){
case 1: //Calcula automàticament
cal_cumagic(n,n*n);
imp_cumagic(n,&cA);
break;
case 2: //Resolució manual
do{
mvprintw(5,10,"Introduir valor (s/n): ");
scanw("%c",&op);
switch(op){
case 'n': //No: sortir
break;
case 's': //Si: assignar valor i recalcular
menu_assigna_valor();
cal_suma(n);
imp_cumagic(n,&cA);
break;
}
}while (op=='s');
break;
case 3: //Resolució amb el ratolí
//Dibuixa i carrega la estructura del enreixat auxiliar amb els valor pertinents
imp_dib_enreixat(10,(n+3)*AMP_C,n,&cB);
imp_ubica_posyx(10,(n+3)*AMP_C,n,&cB);
cal_emplenar_cB(n);
imp_cumagic(n,&cB);
//Activa els events del mouse
rat_act_event_mouse();
while(!quit){
key=getch();
switch(key){
case KEY_MOUSE:
getmouse(&pnt);
switch(pnt.bstate){
//Boto dret:
case BUTTON3_CLICKED:
break;
//Boto esq: seleccionem i transportem valor
case BUTTON1_CLICKED:
if (seleccionar_valor(&erx,&fil,&col)==CASELLA_VALOR){
erx_orig=erx;
fil_orig=fil;
col_orig=col;
val_sel=1;
break;
}
if (val_sel && seleccionar_valor(&erx_dest,&fil_dest,&col_dest)==CASELLA_ZERO){
insertar_valor(erx_orig,erx_dest,fil_orig,col_orig,fil_dest,col_dest);
val_sel=0;
}
break;
};
refresh();
break;
case 'q':
quit=1;
break;
}
}
}
finalitzar();
}
int inicialitzar(){
imp_init_w();
imp_init_color();
}
int finalitzar(){
refresh();
getch();
imp_fi_w();
}
int menu_principal(int *n,int *op){
mvprintw(1,1,"Donam l'ordre del cuadrat màgic: ");
scanw("%d",n);
mvprintw(2,1,"Escull opci: ");
mvprintw(3,5,"1.- Càlcul automàtic ");
mvprintw(4,5,"2.- Emplenar manualment. ");
mvprintw(5,5,"3.- Emplenar amb el ratolí ");
mvscanw(2,16,"%d",op);
refresh();
}
int menu_assigna_valor(){
int fila,columna,valor;
mvprintw(5,10,"1.- Donam fila:");
mvscanw(5,30,"%d",&fila);
mvprintw(5,30," ");
mvprintw(5,10,"1.- Donam columna:");
mvscanw(5,30,"%d",&columna);
mvprintw(5,30," ");
mvprintw(5,10,"1.- Donam valor:");
mvscanw(5,30,"%d",&valor);
mvprintw(5,30," ");
cA.cu[fila][columna].num=valor;
}
int mostrar_fc_valor(t_enreixat *e,int f,int c,int valor){
int y,x;
y=e->pos_erx.y+e->ly+2*ALT_C;
x=e->pos_erx.x;
mvprintw(y,x,"Fila: Columna: Valor: ");
mvprintw(y,x,"Fila: %d Columna: %d Valor:%d",f,c,valor);
}
int seleccionar_valor(t_enreixat **e,int *fila,int *columna){
int f,c,dins_zona_cuadres,valor;
static int f_ant,c_ant,cAB;
switch (cAB){
case CUADRE_A:
imp_desel_fc(f_ant,c_ant,&cA);
break;
case CUADRE_B:
imp_desel_fc(f_ant,c_ant,&cB);
break;
}
if (rat_yx_fc(&cA,n,pnt.y, pnt.x, &f, &c)){
f_ant=f;c_ant=c;cAB=CUADRE_A;
imp_sel_fc(f,c,&cA,&valor);
*fila=f,*columna=c;*e=&cA;
mostrar_fc_valor(&cA,f,c,valor);
dins_zona_cuadres=1;
}
if (rat_yx_fc(&cB,n,pnt.y, pnt.x, &f, &c)){
f_ant=f;c_ant=c;cAB=CUADRE_B;
imp_sel_fc(f,c,&cB,&valor);
*fila=f,*columna=c;*e=&cB;
mostrar_fc_valor(&cB,f,c,valor);
dins_zona_cuadres=1;
}
if (valor) return(CASELLA_VALOR);
if (dins_zona_cuadres) return(CASELLA_ZERO);
return(0);
}
int insertar_valor(t_enreixat *e_orig,t_enreixat *e_dest,int f_orig,int c_orig,int f_dest,int c_dest){
e_dest->cu[f_dest][c_dest].num=e_orig->cu[f_orig][c_orig].num;
e_orig->cu[f_orig][c_orig].num=0;
cal_suma(n);
imp_cumagic(n,e_orig);
imp_cumagic(n,e_dest);
}
cal_cumagic.c
#include "include/cumagic.h"
#include "include/cal_cumagic.h"
int cal_cumagic(int n,int p)
{
int i,j,k;
if (n<=2 || n>MAX || n%2==0) return -1;
cureset(n);
j=n/2;i=j-1;
k=1;
cA.cu[i][j].num=k;
i--;j++;k++;
while (k<=p){
if (i<0) i=n-1;
if (j<0) j=n-1;
if (j>=n) j=0;
if (cA.cu[i][j].num==0){
cA.cu[i][j].num=k;
i--;j++;k++;
}
else{
i--;j--;
}
}
cal_suma(n);
}
int cal_emplenar_cB(int n)
{
int i,j,k=1;
for (i=0;i<n;i++)
for(j=0;j<n;j++)
cB.cu[i][j].num=k++;
}
int cureset(int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++) cA.cu[i][j].num=0;
}
int SumaX(int n)
{
int i,j;
for(i=0;i<n;i++){
cA.sumX[i].num=0;
for(j=0;j<n;j++)
cA.sumX[i].num+=cA.cu[i][j].num;
}
}
int SumaY(int n)
{
int i,j;
for(j=0;j<n;j++){
cA.sumY[j].num=0;
for(i=0;i<n;i++)
cA.sumY[j].num+=cA.cu[i][j].num;
}
}
int SumaDiaA(int n)
{
int i;
cA.DiaA.num=0;
for(i=0;i<n;i++) cA.DiaA.num+=cA.cu[i][i].num;
}
imp_cumagic.c
#include <string.h>
#include "include/cumagic.h"
#include "include/imp_cumagic.h"
int imp_init_w()
{
initscr();
}
void imp_fi_w()
{
endwin();
}
int imp_init_color(){
if (has_colors())if (start_color()==ERR) return -1;
//Inicialitza parells de colors
init_pair(ENREIXAT,COLOR_YELLOW,COLOR_GREEN);
init_pair(NOMBRES,COLOR_BLUE,COLOR_GREEN);
init_pair(ENR_SEL,COLOR_YELLOW,COLOR_WHITE);
init_pair(NOM_SEL,COLOR_RED,COLOR_WHITE);
//Inicialitza fons
bkgd(COLOR_BLACK);
}
void rep_car(int nc,chtype c)
{
int i;
for(i=0;i<nc;i++) addch(c);
}
void lg(int y,int x, int l, chtype Cfirst, chtype C2,int nC2, chtype C3, chtype Clast)
{
int i;
move(y,x);
addch(Cfirst);
rep_car(nC2,C2);
for(i=0;i<=l-2;i++){
addch(C3);
rep_car(nC2,C2);
}
addch(Clast);
}
void imp_dib_enreixat(int y, int x, int n)
{
int i,j;
attron(COLOR_PAIR(ENREIXAT));
//primera linia
lg(y,x,n,ACS_ULCORNER,ACS_HLINE,AMP_C-1,ACS_TTEE,ACS_URCORNER);
for(i=0;i<n-1;i++){
for(j=1;j<ALT_C;j++)
lg(++y,x,n,ACS_VLINE,' ',AMP_C-1,ACS_VLINE,ACS_VLINE);
lg(++y,x,n,ACS_LTEE,ACS_HLINE,AMP_C-1,ACS_PLUS,ACS_RTEE);
}
for(j=1;j<ALT_C;j++)
lg(++y,x,n,ACS_VLINE,' ',AMP_C-1,ACS_VLINE,ACS_VLINE);
//Ultima linia
lg(++y,x,n,ACS_LLCORNER,ACS_HLINE,AMP_C-1,ACS_BTEE,ACS_LRCORNER);
attroff(COLOR_PAIR(ENREIXAT));
}
void imp_cuadre(int y,int x,int alt,int amp)
{
int i;
lg(y,x,1,ACS_ULCORNER,ACS_HLINE,amp-1,ACS_HLINE,ACS_URCORNER);
for(i=0;i<alt;i++)
lg(++y,x,1,ACS_VLINE,' ',amp-1,' ',ACS_VLINE);
lg(++y,x,1,ACS_LLCORNER,ACS_HLINE,amp-1,ACS_HLINE,ACS_LRCORNER);
}
void imp_ubica_posyx(int y, int x,int n,t_enreixat *e)
{
int i,j,posy,posx,num,px_cas,py_cas;
//Ubica les posicions i el tamany del enreixat
e->pos_erx.y=y;
e->pos_erx.x=x;
e->ly=n*ALT_C;
e->lx=n*AMP_C;
//Ubica les posicions d'impresió del numero i les posicions i tamany de cada cel.la
px_cas=x; py_cas=y;
posy=y+(int)(ALT_C/2);
posx=x+(int)(AMP_C/4);
num=1;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
e->cu[i][j].pos_num.x=posx;
e->cu[i][j].pos_num.y=posy;
e->cu[i][j].pos_cas.x=px_cas;
e->cu[i][j].pos_cas.y=py_cas;
e->cu[i][j].lx=AMP_C;
e->cu[i][j].ly=ALT_C;
posx+=AMP_C;px_cas+=AMP_C;
}
posx=x+(int)(AMP_C/4);px_cas=x;
posy+=ALT_C;py_cas+=ALT_C;
}
//Ubica sumX
for(i=0;i<n;i++){
e->sumX[i].pos_num.x=e->cu[0][n-1].pos_num.x+AMP_C;
e->sumX[i].pos_num.y=e->cu[i][n-1].pos_num.y;
}
//Ubica sumY
for(i=0;i<n;i++){
e->sumY[i].pos_num.x=e->cu[n-1][i].pos_num.x;
e->sumY[i].pos_num.y=e->cu[n-1][i].pos_num.y+ALT_C;
}
//Ubica Diagonal A
e->DiaA.pos_num.x=e->cu[n-1][n-1].pos_num.x + AMP_C;
e->DiaA.pos_num.y=e->cu[n-1][n-1].pos_num.y + ALT_C;
//Ubica Diagonal B
e->DiaB.pos_num.x=e->cu[n-1][0].pos_num.x - AMP_C;
e->DiaB.pos_num.y=e->cu[n-1][0].pos_num.y + ALT_C;
}
int imp_cumagic(int n,t_enreixat *e)
{
int i,j,y,x;
attron(COLOR_PAIR(NOMBRES));
for(i=0;i<n;i++)
for(j=0;j<n;j++){
y=e->cu[i][j].pos_num.y;x=e->cu[i][j].pos_num.x;
if (e->cu[i][j].num) mvprintw(y,x,"%3d",e->cu[i][j].num);
if (!e->cu[i][j].num) mvprintw(y,x," ");
}
attroff(COLOR_PAIR(NOMBRES));
//Imprimir sumX i sumY
for(i=0;i<n;i++){
y=e->sumX[i].pos_num.y;x=e->sumX[i].pos_num.x;
if (e->sumX[i].num) mvprintw(y,x,"%3d",e->sumX[i].num);
if (!e->sumX[i].num) mvprintw(y,x," ");
y=e->sumY[i].pos_num.y;x=e->sumY[i].pos_num.x;
if (e->sumY[i].num) mvprintw(y,x,"%3d",e->sumY[i].num);
if (!e->sumY[i].num) mvprintw(y,x," ",e->sumY[i].num);
}
//Imprimir diagonals
y=e->DiaA.pos_num.y;x=e->DiaA.pos_num.x;
if (e->DiaA.num) mvprintw(y,x,"%3d",e->DiaA.num);
if (!e->DiaA.num) mvprintw(y,x," ",e->DiaA.num);
y=e->DiaB.pos_num.y;x=e->DiaB.pos_num.x;
if (e->DiaB.num) mvprintw(y,x,"%3d",e->DiaB.num);
if (!e->DiaB.num) mvprintw(y,x," ",e->DiaB.num);
refresh();
}
int imp_sel_fc(int fila,int columna,t_enreixat *e,int *valor)
{
attron(COLOR_PAIR(NOM_SEL));
*valor=e->cu[fila][columna].num;
mvprintw(e->cu[fila][columna].pos_num.y,e->cu[fila][columna].pos_num.x,"%3d",e->cu[fila][columna].num);
attroff(COLOR_PAIR(NOM_SEL));
}
int imp_desel_fc(int fila,int columna,t_enreixat *e)
{
int valor;
valor=e->cu[fila][columna].num;
attron(COLOR_PAIR(NOMBRES));
if (valor > 0) mvprintw(e->cu[fila][columna].pos_num.y,e->cu[fila][columna].pos_num.x,"%3d",valor);
if (valor <=0) mvprintw(e->cu[fila][columna].pos_num.y,e->cu[fila][columna].pos_num.x," ");
attroff(COLOR_PAIR(NOMBRES));
}
rat_cumagic.c
#include "include/rat_cumagic.h"
int rat_act_event_mouse()
{
raw();
keypad(stdscr,TRUE);
mousemask(ALL_MOUSE_EVENTS,0);
}
int rat_yx_fc(t_enreixat *e,int n,int y, int x, int *fila, int *columna)
{
int i,j,x_ini,x_fi,y_ini,y_fi,ok=1;
//mvprintw(25,25,"rat_yx_fc: y:%d x:%d %d %d %d %d",y,x,e->pos_erx.y,e->pos_erx.x,e->pos_erx.y + e->ly,e->pos_erx.x + e->lx);getch();
if ((y <= e->pos_erx.y) || (y >= (e->pos_erx.y + e->ly)) || (x <= e->pos_erx.x) || (x >= (e->pos_erx.x + e->lx))) return(0);
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{
x_ini=e->cu[i][j].pos_cas.x;
x_fi=x_ini+e->cu[i][j].lx;
y_ini=e->cu[i][j].pos_cas.y;
y_fi=y_ini+e->cu[i][j].ly;
//mvprintw(20,20,"x0: %d x1: %d y0: %d y1: %d",x_ini,x_fi,y_ini,y_fi);getch();
if ((x >= x_ini) && (x <= x_fi) && (y >= y_ini) && (y <= y_fi))
{
*fila=i;
*columna=j;
//mvprintw(20,20,"FILA: %d COLUMNA: %d",*fila,*columna);getch();
return(1);
}
}
return(0);
}