diff --git a/index.html b/index.html
index e4b78ea..c0d2368 100644
--- a/index.html
+++ b/index.html
@@ -1,10 +1,9 @@
-
-
+
- Vite + React + TS
+ WORDLE(demo) | kakutory
diff --git a/public/maton.png b/public/maton.png
new file mode 100644
index 0000000..ce637a6
Binary files /dev/null and b/public/maton.png differ
diff --git a/src/App.css b/src/App.css
deleted file mode 100644
index b9d355d..0000000
--- a/src/App.css
+++ /dev/null
@@ -1,42 +0,0 @@
-#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-.logo {
- height: 6em;
- padding: 1.5em;
- will-change: filter;
- transition: filter 300ms;
-}
-.logo:hover {
- filter: drop-shadow(0 0 2em #646cffaa);
-}
-.logo.react:hover {
- filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
diff --git a/src/App.tsx b/src/App.tsx
index afe48ac..bff786b 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,35 +1,47 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
-
-function App() {
- const [count, setCount] = useState(0)
-
- return (
- <>
-
- Vite + React
-
-
-
- Edit src/App.tsx
and save to test HMR
-
-
-
- Click on the Vite and React logos to learn more
-
- >
- )
-}
+import { useState } from 'react';
+
+import { Answer } from './components/answer';
+import { Keyboard } from './components/keyboard';
+
+export const App = (): JSX.Element =>{
+ // 6*5の配列の初期化
+ const initAnswerList: string[][] = new Array(6);
+ for (let i=0; i<6; i++){
+ initAnswerList[i] = new Array(5).fill("");
+ }
+
+ // 回答一覧
+ // キーボードの文字入力により更新
+ const [ answerList, setAnswerList ] = useState(initAnswerList);
+
+ // 回答の判定を行うフラグ
+ // キーボードのEnter入力により更新
+ const [ judge, setJudge ] = useState(false);
-export default App
+ // 現在の状態
+ // playing: ゲーム中
+ // success: 成功
+ // fail: 失敗
+ const [ gameStatus, setGameStatus ] = useState("playing");
+
+ // 正解単語
+ const [ answerWord ] = useState("MARIO");
+
+ return (
+
+ );
+}
diff --git a/src/components/answer.tsx b/src/components/answer.tsx
new file mode 100644
index 0000000..38a8dc3
--- /dev/null
+++ b/src/components/answer.tsx
@@ -0,0 +1,199 @@
+import React, { useState, useEffect } from 'react';
+
+type Props = {
+ answerList: string[][];
+ judge: boolean;
+ setJudge: React.Dispatch>;
+ answerWord: string;
+ gameStatus: string;
+ setGameStatus: React.Dispatch>;
+}
+
+export const Answer = (props: Props) => {
+
+ // 回答のCSSスタイル
+ const answerStyle: React.CSSProperties = {
+ borderSpacing: '6px 6px',
+ display: 'flex',
+ justifyContent: 'center',
+ marginBottom: '40px',
+ marginTop: '100px',
+ };
+
+ /* td要素のCSSスタイル */
+ // Whiteスタイル
+ const whiteTdStyle: React.CSSProperties = {
+ border: '2px solid rgb(217, 217, 217)',
+ width: '60px',
+ height: '70px',
+
+ fontSize: '30px',
+ fontWeight: 'bold',
+ textAlign: 'center',
+ lineHeight: '60px',
+
+ // 文字色
+ color: 'Black', // 背景色Whiteの時のみ
+
+ // 背景色
+ backgroundColor: 'White',
+
+ };
+
+ // Blackスタイル
+ const blackTdStyle = {...whiteTdStyle};
+ blackTdStyle['color'] = 'White';
+ blackTdStyle['backgroundColor'] = '3a3a3c';
+
+ // Yellowスタイル
+ const yellowTdStyle = {...whiteTdStyle};
+ yellowTdStyle['color'] = 'White';
+ yellowTdStyle['backgroundColor'] = 'b59f3b';
+
+ // Greenスタイル
+ const greenTdStyle = {...whiteTdStyle};
+ greenTdStyle['color'] = 'White';
+ greenTdStyle['backgroundColor'] = '538d4e';
+
+ // ラウンド
+ const [ round, setRound ] = useState(0);
+
+ // リストの初期化
+ const initMatchList: string[][] = new Array(6);
+ for (let i=0; i<6; i++){
+ initMatchList[i] = new Array(5).fill("White");
+ }
+
+ // 回答欄のCSSリスト
+ // White: 判定していない
+ // Black: 文字も位置も無一致
+ // Yellow: 文字のみ一致
+ // Green: 文字も位置も一致
+ // const [ matchList, setMatchList ] = useState(initMatchList);
+
+ // リストの初期化
+ const initMatchStyleList: React.CSSProperties[][] = new Array(6);
+ for (let i=0; i<6; i++){
+ initMatchStyleList[i] = new Array(5).fill(whiteTdStyle);
+ }
+
+ // 回答欄のCSSリスト
+ // White: 判定していない
+ // Black: 文字も位置も無一致
+ // Yellow: 文字のみ一致
+ // Green: 文字も位置も一致
+ const [ matchStyleList, setMatchStyleList ] = useState(initMatchStyleList);
+
+ // 単語一致判定
+ const wordMatchJudgement = () => {
+ // 一度ディープコピーする
+ const tmpMatchStyleList = Array.from(matchStyleList);
+
+ // 1文字ずつ判定
+ for (let i=0; i<5; i++){
+
+ // 文字が一致
+ if (props.answerWord.indexOf(props.answerList[round-1][i]) !== -1){
+
+ // 位置も一致(Green)
+ if (props.answerList[round-1][i] === props.answerWord[i]){
+ tmpMatchStyleList[round-1][i] = greenTdStyle;
+ }
+
+ // 文字だけ一致(Yellow)
+ else {
+ tmpMatchStyleList[round-1][i] = yellowTdStyle;
+ }
+ }
+
+ // 文字も位置も一致していない(Black)
+ else {
+ tmpMatchStyleList[round-1][i] = blackTdStyle;
+ }
+ }
+
+ console.log(tmpMatchStyleList[round-1]);
+ return tmpMatchStyleList;
+ }
+
+ // クリア判定
+ const clearJudgement = () => {
+
+ // ワードを抽出
+ const wordList = [];
+ for (let j = 0; j < 5; j++) {
+ wordList.push(props.answerList[round-1][j]);
+ }
+ const submitWord = wordList.join("");
+ console.log(submitWord);
+
+ if (submitWord == props.answerWord){
+ alert("clear!!");
+ return "success";
+ }
+
+ else if (round == 6) {
+ alert("fail...");
+ return "fail";
+ }
+
+ return "playing";
+ }
+
+
+ // Appコンポーネントのjudgeが変化した時に呼ばれる
+ useEffect(() => {
+
+ // Enterを押したら
+ if (props.judge === true){
+ // 一度フラグをおろす
+ props.setJudge(false);
+ }
+
+ // フラグをおろしてからここへ
+ else {
+ // コンポーネント初期化時にここを通る
+ if (round == 0){
+ setRound(round+1); // ラウンドを1に
+ return;
+ }
+
+ // ゲーム継続中なら
+ if (props.gameStatus == "playing"){
+ // 単語一致判定
+ const tmpMatchStyleList = wordMatchJudgement();
+
+ // クリア判定
+ clearJudgement();
+
+ // スタイル更新
+ setMatchStyleList(tmpMatchStyleList);
+ // ラウンド更新
+ setRound(round+1);
+
+ console.log(tmpMatchStyleList[0]);
+ }
+ }
+
+ }, [props.judge]);
+
+
+ return (
+ // mapにより回答table作成
+
+
+
+
+ {props.answerList.map((answer, i) => (
+
+ {answer.map((letter, j) => (
+ {letter} |
+ ))}
+
+ ))}
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/keyboard.tsx b/src/components/keyboard.tsx
new file mode 100644
index 0000000..21e47f7
--- /dev/null
+++ b/src/components/keyboard.tsx
@@ -0,0 +1,144 @@
+import React, { useState } from "react";
+
+type appProps = {
+ setAnswerList: React.Dispatch>;
+ setJudge: React.Dispatch>;
+};
+
+type Props = {
+ rowcnt: number;
+ setColumncnt: React.Dispatch>;
+ columncnt: number;
+ setRowcnt: React.Dispatch>;
+ setAnswerList: React.Dispatch>;
+ keyLayout: string[];
+ setJudge: React.Dispatch>;
+};
+
+const KeyboardRow = (props: Props) => {
+ const updateAnswer = (prevState: string[][], letter: string, row: number, column: number) => {
+ const tmpList = Array.from(prevState);
+ tmpList[row][column] = letter;
+
+ return tmpList;
+ }
+
+ const handleClick = (event: React.MouseEvent) => {
+ const letter = event.currentTarget.value;
+
+ // Enter入力
+ if (letter == "Enter") {
+ // 文字数不足
+ if (props.columncnt < 5){
+ alert("文字数が足りません");
+ }
+
+ // 5文字入力した状態
+ else {
+ // フラグ送信(正解判定の依頼)
+ props.setJudge(true);
+
+ // 列数リセット
+ props.setColumncnt(0);
+
+ // 次の行へ移行
+ props.setRowcnt((prev) => prev+1);
+ }
+ }
+
+ // Delete入力
+ else if(letter == "Delete"){
+ // 1文字以上入力
+ if(props.columncnt > 0){
+ props.setAnswerList((prevState) => updateAnswer(prevState, "", props.rowcnt, props.columncnt-1));
+ props.setColumncnt((prev) => prev-1);
+ }
+ }
+
+ // アルファベット入力
+ else if (props.columncnt < 5) {
+ props.setAnswerList((prevState) => updateAnswer(prevState, letter, props.rowcnt, props.columncnt));
+ props.setColumncnt((prev) => prev+1);
+ }
+ };
+
+ // キーボードのCSSスタイル
+ const keyboardStyle: React.CSSProperties = {
+ borderSpacing: "6px 6px",
+ display: "flex",
+ justifyContent: "center"
+ };
+
+ // ボタンのCSSスタイル
+ const buttonStyle: React.CSSProperties = {
+ backgroundColor: "rgb(217, 217, 217)",
+ borderRadius: "4px",
+ border: "none",
+ width: "45px",
+ height: "60px",
+
+ fontSize: "13px",
+ fontWeight: "bold",
+ cursor: "pointer"
+ };
+
+ return (
+ // mapによりキーボードtable作成
+
+
+
+ {props.keyLayout.map((key, i) => (
+
+ {/* ボタン */}
+
+ |
+ ))}
+
+
+
+ );
+};
+
+
+export const Keyboard = (props: appProps) => {
+ const upKeyLayout: string[] = ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"];
+ const middleKeyLayout: string[] = ["A", "S", "D", "F", "G", "H", "J", "K", "L"];
+ const downKeyLayout: string[] = ["Enter", "Z", "X", "C", "V", "B", "N", "M", "Delete"];
+
+ const [rowcnt,setRowcnt] = useState(0);
+ const [columncnt,setColumncnt] = useState(0);
+
+ return (
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index 6119ad9..c798e28 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,4 +1,4 @@
-:root {
+/* :root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
@@ -65,4 +65,4 @@ button:focus-visible {
button {
background-color: #f9f9f9;
}
-}
+} */
diff --git a/src/main.tsx b/src/main.tsx
index 3d7150d..9702424 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,6 +1,6 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
-import App from './App.tsx'
+import { App } from './App.tsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(