Skip to content

Commit

Permalink
[Add a Play]: Schulte tables game - issue: #1381 (#1382)
Browse files Browse the repository at this point in the history
* [Add a Play]: Schulte tables game - issue: #1381

* Remove comment of SchulteTables

* Modify shuffleArray.js and shorten the code using Array.from

---------

Co-authored-by: Priyankar Pal <[email protected]>
  • Loading branch information
mhShohan and priyankarpal committed Dec 1, 2023
1 parent c8a46aa commit b3ffbc3
Show file tree
Hide file tree
Showing 11 changed files with 288 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/plays/schulte-tables/GameTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useEffect, useState } from 'react';
import shuffle from './utils/shuffleArray';
import SchulteTable from './components/SchulteTable';
import timeFormatter from './utils/timeFormatter';

const GameTable = () => {
const [data, setData] = useState(shuffle());
const [start, setStart] = useState(false);
const [nextNumber, setNextNumber] = useState(1);
const [result, setResult] = useState(null);

const restart = () => {
setResult(null);
setNextNumber(1);
setStart(true);
};

useEffect(() => {
const shuffledData = shuffle();
setData(shuffledData);
}, [nextNumber]);

return (
<main>
<h1 className="game-title mb-3">Schulte Table</h1>
{start && !result ? (
<SchulteTable
data={data}
nextNumber={nextNumber}
setNextNumber={setNextNumber}
setResult={setResult}
setStart={setStart}
start={start}
/>
) : (
<section className="center col">
{!result && (
<>
<button className="start-btn" onClick={() => setStart(true)}>
start
</button>
<p className="description">
Schulte tables are tables with randomly arranged characters, usually numbers used to
check and develop the speed of their visual search in a specific order. These tables
were originally developed by the German psychotherapist Walter Schulte as a
psychodiagnostic test for studying the properties of attention.
</p>
</>
)}
</section>
)}
{result && (
<section className="result-section">
<h1>Completed in {timeFormatter(result)}</h1>
<br />
<button className="start-btn" onClick={restart}>
Restart
</button>
<p className="description">
Schulte tables are tables with randomly arranged characters, usually numbers used to
check and develop the speed of their visual search in a specific order. These tables
were originally developed by the German psychotherapist Walter Schulte as a
psychodiagnostic test for studying the properties of attention.
</p>
</section>
)}
</main>
);
};

export default GameTable;
30 changes: 30 additions & 0 deletions src/plays/schulte-tables/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Schulte tables

Schulte tables are tables with randomly arranged characters, usually numbers used to check and develop the speed of their visual search in a specific order. These tables were originally developed by the German psychotherapist Walter Schulte as a psychodiagnostic test for studying the properties of attention.

## Play Demographic

- Language: JavaScript
- Level: Intermediate

## Creator Information

- [GitHub](https://github.com/mhShohan)
- [LinkedIn](https://www.linkedin.com/in/mehdi-hasan-shohan/)

## Implementation Details

Implementation details of Schulte tables Game
- Components
- `Timer.jsx`: A component to track the time taken for the user to complete the table.
- `SchulteTable.jsx`: This component will represent the Schulte table itself.
- `Button.jsx` - Box of SchulteTable
- `GameTable.jsx` - The main file of the game
- Utility function/files
- `generateColor.js` - generate random RGB color
- `shuffleArray.js` - shuffle the array on function call
- `timeFormatter.js` - format time
- Display the Table: Render the Schulte table on the screen. You can use a grid layout to arrange the cells. Iterate through the array of characters and create Cell components for each one.
- Styling:Apply CSS styles to make your Schulte table visually appealing and user-friendly.


18 changes: 18 additions & 0 deletions src/plays/schulte-tables/SchulteTables.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import './styles.css';
import PlayHeader from 'common/playlists/PlayHeader';
import GameTable from './GameTable';

function SchulteTables(props) {
return (
<>
<div className="play-details">
<PlayHeader play={props} />
<div className="play-details-body">
<GameTable />
</div>
</div>
</>
);
}

export default SchulteTables;
13 changes: 13 additions & 0 deletions src/plays/schulte-tables/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import generateColor from '../utils/generateColor';

const Button = ({ handleClick, value }) => {
const color = generateColor();

return (
<button className="btn" style={{ backgroundColor: color }} onClick={() => handleClick(value)}>
{value}
</button>
);
};

export default Button;
32 changes: 32 additions & 0 deletions src/plays/schulte-tables/components/SchulteTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Button from './Button';
import Timer from './Timer';

const SchulteTable = ({ nextNumber, setNextNumber, data, setStart, start, setResult }) => {
const handleClick = (value) => {
if (value === nextNumber) {
setNextNumber((p) => p + 1);
}
};

return (
<section>
<div className="flex">
<h1>
Time:{' '}
<Timer nextNumber={nextNumber} setResult={setResult} setStart={setStart} start={start} />
</h1>
<h1>Next: {nextNumber}</h1>
</div>
<div className="center col">
<div className="table">
{data.map((value, i) => (
<Button handleClick={handleClick} key={i} value={value} />
))}
</div>
<p className="hints">Hints: Click on box which contains the "Next" number!</p>
</div>
</section>
);
};

export default SchulteTable;
26 changes: 26 additions & 0 deletions src/plays/schulte-tables/components/Timer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useEffect, useState } from 'react';

const Timer = ({ nextNumber, start, setStart, setResult }) => {
const [timeCount, setTimeCount] = useState(0);

useEffect(() => {
const timer = setInterval(() => {
if (start) {
setTimeCount((prevSeconds) => prevSeconds + 1);
}
}, 1000);

if (nextNumber === 26) {
clearInterval(timer);
setResult(timeCount);
setStart(false);
setTimeCount(0);
}

return () => clearInterval(timer);
}, [timeCount, start]);

return <span>{timeCount}s</span>;
};

export default Timer;
Binary file added src/plays/schulte-tables/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions src/plays/schulte-tables/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* enter stlyes here */
.center {
display: flex;
justify-content: center;
align-items: center;
}

.col {
flex-direction: column;
}

h1 {
text-align: center;
}

.game-title {
text-align: center;
font-size: 4rem;
}

.table {
display: grid;
grid-template-columns: repeat(5, 60px);
border: 2px solid grey;
margin-top: 1rem;
}

.btn {
height: 60px;
border: none;
outline: none;
font-size: 18px;
cursor: pointer;
}

.flex {
display: flex;
width: 300px;
margin: 0 auto;
justify-content: space-between;
}

.start-btn {
background: #278383;
padding: .6rem 3rem;
font-size: 18px;
border: 1px solid #062c2c;
outline: none;
color: aliceblue;
border-radius: 50px;
text-transform: uppercase;
cursor: pointer;
}

.result-section {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}

.hints {
margin: 1rem;
}
.description{
max-width: 500px;
text-align: center;
margin: 2rem auto;
}
9 changes: 9 additions & 0 deletions src/plays/schulte-tables/utils/generateColor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const generateColor = () => {
const r = Math.floor(Math.random() * 255);
const g = Math.floor(Math.random() * 255);
const b = Math.floor(Math.random() * 255);

return `rgba(${r},${g},${b},0.5)`;
};

export default generateColor;
12 changes: 12 additions & 0 deletions src/plays/schulte-tables/utils/shuffleArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const shuffle = () => {
const array = Array.from({ length: 25 }, (_, i) => i + 1);

for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}

return array;
};

export default shuffle;
8 changes: 8 additions & 0 deletions src/plays/schulte-tables/utils/timeFormatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const timeFormatter = (time) => {
const min = Math.floor(time / 60);
const sec = time % 60;

return `${min} Minutes ${sec} Seconds`;
};

export default timeFormatter;

0 comments on commit b3ffbc3

Please sign in to comment.