import { createSlice } from '@reduxjs/toolkit'; import type { PayloadAction } from '@reduxjs/toolkit'; function shuffle(array: Array): Array { let currentIndex = array.length; // While there remain elements to shuffle... while (currentIndex != 0) { // Pick a remaining element... let randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; // And swap it with the current element. [array[currentIndex], array[randomIndex]] = [ array[randomIndex], array[currentIndex]]; } return array; } interface QuizState { userAnswers: (string | boolean)[][]; // хранит перемещаемые элементы каждого списка ответов questions: string[][]; correctAnswers: (string | boolean)[][];// ответы для вопрсов, в случае с matching просто правильная последоавтельность, для sorting аналогично, для choosе последоватеьность boolean quizTypes: Array<"M" | "S" | "C">; isTestingDone: boolean// запрет на взаимодействие с квизом после окончания тестирования, чтобю юзер не наглел } const initialState: QuizState = { userAnswers: [], correctAnswers: [], quizTypes: [], questions:[], isTestingDone: false, }; const listsSlice = createSlice({ name: 'lists', initialState, reducers: { addList: (state, action: PayloadAction<{ index: number; items: string[]; questions: string[]; answers: (string|boolean)[]; quizType : "S" | "M" | "C"}>) => { const { index, items,questions,answers,quizType} = action.payload; state.questions.splice(index, 1, questions); state.userAnswers.splice(index, 1, items); // с нулём создаётся по 2 экземпляра, видно в отладке state.quizTypes.splice(index, 1, quizType); // state.correctAnswers.splice(index, 1, answers); }, setDraggedItems: (state, action: PayloadAction<{ index: number; items: (string|boolean)[] }>) => { const { index, items } = action.payload; if (index >= 0 && index < state.userAnswers.length) { state.userAnswers[index] = items; // обновляем конкретный список } }, setCheckedItems: (state, action: PayloadAction<{ index: number; items: boolean[] }>) => { const { index, items } = action.payload; if (index >= 0 && index < state.userAnswers.length) { state.userAnswers[index] = items; // обновляем конкретный список } }, mixUp: (state) => { state.userAnswers = state.userAnswers.map((list,index) => { if(typeof(state.correctAnswers[index][0])==="boolean"){ list.map(()=>false); let indexes = shuffle( list.map((_,idx)=>idx)); state.correctAnswers[index]=state.correctAnswers[index].map((_,i,arr)=>arr[indexes[i]]) state.questions[index]=state.questions[index].map((_,i,arr)=>arr[indexes[i]]) return list.map(()=>false) } return shuffle(list); }) }, stopTesting: (state) => { state.isTestingDone = true; }, startTesting: (state) => { state.isTestingDone = false; } }, }); // Экспортируем действия и редьюсер export const { addList, setDraggedItems,setCheckedItems, mixUp, startTesting, stopTesting } = listsSlice.actions; export type { QuizState } export default listsSlice.reducer;