From 396d7dfd6b884e669ebfcb2013ee15cb9e0ef434 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Feb 23 2025 17:06:34 +0000 Subject: shisen: more options --- diff --git a/onefile/shisen.c b/onefile/shisen.c index 0577638..f1ebd63 100644 --- a/onefile/shisen.c +++ b/onefile/shisen.c @@ -49,8 +49,11 @@ Pos selected = { -1, -1 }; Track tracks[COUNT]; int tracksCount; Animation bgtex; +int glyphsMask = 15; +int mode; void clearBoard() { + mode = 0; memset(tracks, 0, sizeof(tracks)); memset(board, 0, sizeof(board)); tracksCount = 0; @@ -110,27 +113,27 @@ int loadLetters(const char *filename, int rows, int cols) { } -void shuffleLetters() { +void shuffleLetters(int glyps) { for(int i = 0; i < lettersCount; ++i) { int j = randomNumber(i, lettersCount - 1); if (j != i) { Letter l = letters[i]; letters[i] = letters[j]; letters[j] = l; } Letter *l = &letters[i]; assert(l->glyphsCount > 0); - for(int j = 1; j < l->glyphsCount; ++j) { - int k = randomNumber(j, l->glyphsCount - 1); - if (k != j) { Animation g = l->glyphs[j]; l->glyphs[j] = l->glyphs[k]; l->glyphs[k] = g; } - } + int gc = 0; + Animation g[4] = {}; + for(int j = 0; j < l->glyphsCount; ++j) + if (glyps & (1 << j)) g[gc++] = l->glyphs[j]; + if (!gc) g[gc++] = l->glyphs[0]; - if (l->glyphsCount <= 1) { - for(int j = 0; j < 4; ++j) - l->g[j] = l->glyphs[0]; - } else { - l->g[0] = l->glyphs[0]; - for(int j = 1; j < 4; ++j) - l->g[j] = l->glyphs[(j-1)%(l->glyphsCount-1) + 1]; + for(int j = 0; j < gc; ++j) { + int k = randomNumber(j, gc - 1); + if (k != j) { Animation a = g[j]; g[j] = g[k]; g[k] = a; } } + for(int j = 0; j < 4; ++j) + l->g[j] = g[j%gc]; + for(int j = 0; j < 4; ++j) { int k = randomNumber(j, 3); if (k != j) { Animation g = l->g[j]; l->g[j] = l->g[k]; l->g[k] = g; } @@ -140,18 +143,25 @@ void shuffleLetters() { } -void generateBoard() { +void generateBoard(int glyphsMask, int maxLetters) { + if (maxLetters < 1) maxLetters = 1; + clearBoard(); - shuffleLetters(); + shuffleLetters(glyphsMask); + int indices[COUNT]; for(int i = 0; i < COUNT; ++i) indices[i] = i; + + int lc = lettersCount > maxLetters ? lettersCount : maxLetters; for(int i = 0; i < COUNT; ++i) { int j = randomNumber(i, COUNT-1); int id = indices[j]; indices[j] = indices[i]; indices[i] = id; - Letter *l = &letters[ (id/4)%lettersCount ]; + Letter *l = &letters[ (id/4)%lc ]; board[i/COLS][i%COLS].l = l; board[i/COLS][i%COLS].g = l->g[id%4]; } + + mode = 1; } @@ -268,7 +278,6 @@ void init() { windowStop(); return; } - generateBoard(); } @@ -277,10 +286,6 @@ void draw() { double h = windowGetHeight(); double dt = windowGetFrameTime(); - double kw = w/(cellWidth*(COLS + 2)); - double kh = h/(cellHeight*(ROWS + 2)); - double k = kw < kh ? kw: kh; - saveState(); translate(w*0.5, h*0.5); @@ -302,71 +307,114 @@ void draw() { } - zoom(k); - translate(-0.5*COLS*cellWidth, -0.5*ROWS*cellHeight); - strokeWidth(0.1*cellWidth); - - double mx = mouseTransformedX(); - double my = mouseTransformedY(); - Pos hover = {}; - hover.c = (int)floor(mx/cellWidth); - hover.r = (int)floor(my/cellHeight); - if (mouseWentDown("left")) { - Track t = findTrack(selected, hover); - if (t.len) { - t.tm = 1; - Cell *ca = &board[selected.r][selected.c]; - Cell *cb = &board[hover.r][hover.c]; - ca->l = cb->l = NULL; - ca->tm = cb->tm = t.tm; - tracks[tracksCount++] = t; + if (mode == 0) { + double kw = w/(cellWidth*6); + double kh = h/(cellHeight*3); + double k = kw < kh ? kw: kh; + if (k > 1) k = 1; + zoom(k); + noStroke(); + translate(-cellWidth*2, -0.5*cellHeight); + assert(letters[0].glyphsCount >= 4); + + int mc = (int)floor(mouseTransformedX()/cellWidth); + int mr = (int)floor(mouseTransformedY()/cellHeight); + if (!mr && mc >= 0 && mc < 4 && mouseWentDown("left")) glyphsMask ^= 1 << mc; + + for(int i = 0; i < 4; ++i) { + double s = !mr && mc == i ? 1 : 0.9; + double d = (1 - s)/2; + double a = glyphsMask & (1 << i) ? 1.0 : 0.5; + fill(colorByRGBA(1, 1, 1, a)); + rectTextured(letters[0].glyphs[i], (i + d)*cellWidth, d*cellHeight, cellWidth*s, cellHeight*s); } - selected = hover; - } - if (keyWentDown("h")) hint(); - - // draw letters - for(int r = 0; r < ROWS; ++r) - for(int c = 0; c < COLS; ++c) { - Cell *cell = &board[r][c]; - if (!cell->g) continue; - - double a = 1; - if (cell->tm) { - cell->tm -= dt/RMTIME; - if (cell->tm <= 0) { - cell->g = NULL; - cell->tm = 0; - continue; + if (glyphsMask) { + noFill(); + stroke(colorByRGBA(0.0, 0.0, 0.0, 0.75)); + textAlign(HALIGN_CENTER, HALIGN_CENTER); + textSize(cellHeight*0.5); + text(2*cellWidth, 1.5*cellHeight, "press enter"); + if ( keyWentDown("any enter") + || (mr == 1 && mc >= 0 && mc < 4 && mouseWentDown("left")) ) + generateBoard(glyphsMask, 30); + } + } else { + double kw = w/(cellWidth*(COLS + 2)); + double kh = h/(cellHeight*(ROWS + 2)); + double k = kw < kh ? kw: kh; + zoom(k); + + translate(-0.5*COLS*cellWidth, -0.5*ROWS*cellHeight); + strokeWidth(0.1*cellWidth); + + if (keyWentDown("escape")) clearBoard(); + + double mx = mouseTransformedX(); + double my = mouseTransformedY(); + Pos hover = {}; + hover.c = (int)floor(mx/cellWidth); + hover.r = (int)floor(my/cellHeight); + if (mouseWentDown("left")) { + Track t = findTrack(selected, hover); + if (t.len) { + t.tm = 1; + Cell *ca = &board[selected.r][selected.c]; + Cell *cb = &board[hover.r][hover.c]; + ca->l = cb->l = NULL; + ca->tm = cb->tm = t.tm; + tracks[tracksCount++] = t; } - a = cell->tm; + selected = hover; } - saveState(); - noStroke(); - fill(colorByRGBA(1.0, 1.0, 1.0, a)); - if (a == 1 && c == hover.c && r == hover.r) fill(colorByRGBA(0.9, 0.9, 0.9, a)); - if (a == 1 && c == selected.c && r == selected.r) fill(colorByRGBA(0.8, 0.8, 0.8, a)); - rectTextured(cell->g, c*cellWidth, r*cellHeight, cellWidth, cellHeight); - restoreState(); - } + Letter *hl = mouseDown("right") ? get(hover) : NULL; + + if (keyWentDown("h")) hint(); + + // draw letters + for(int r = 0; r < ROWS; ++r) + for(int c = 0; c < COLS; ++c) { + Cell *cell = &board[r][c]; + if (!cell->g) continue; + + double a = 1; + if (cell->tm) { + cell->tm -= dt/RMTIME; + if (cell->tm <= 0) { + cell->g = NULL; + cell->tm = 0; + continue; + } + a = cell->tm; + } - // draw tracks - int j = 0; - for(int i = 0; i < tracksCount; ++i) { - Track *t = &tracks[i]; - t->tm -= dt/RMTIME; - if (t->tm <= 0) { j = i + 1; continue; } - saveState(); - stroke(colorByRGBA(1, 0, 0, t->tm)); - for(int k = 0; k < t->len; ++k) - lineTo((t->p[k].c + 0.5)*cellWidth, (t->p[k].r + 0.5)*cellHeight); - strokePath(); - restoreState(); + saveState(); + noStroke(); + fill(colorByRGBA(1.0, 1.0, 1.0, a)); + if (a == 1 && hl && hl == cell->l ) fill(colorByRGBA(0.9, 0.9, 0.9, a)); + if (a == 1 && c == hover.c && r == hover.r) fill(colorByRGBA(0.9, 0.9, 0.9, a)); + if (a == 1 && c == selected.c && r == selected.r) fill(colorByRGBA(0.8, 0.8, 0.8, a)); + rectTextured(cell->g, c*cellWidth, r*cellHeight, cellWidth, cellHeight); + restoreState(); + } + + // draw tracks + int j = 0; + for(int i = 0; i < tracksCount; ++i) { + Track *t = &tracks[i]; + t->tm -= dt/RMTIME; + if (t->tm <= 0) { j = i + 1; continue; } + saveState(); + stroke(colorByRGBA(1, 0, 0, t->tm)); + for(int k = 0; k < t->len; ++k) + lineTo((t->p[k].c + 0.5)*cellWidth, (t->p[k].r + 0.5)*cellHeight); + strokePath(); + restoreState(); + } + tracksCount -= j; + memmove(tracks, tracks + j, sizeof(*tracks)*tracksCount); } - tracksCount -= j; - memmove(tracks, tracks + j, sizeof(*tracks)*tracksCount); restoreState(); }