From a49c9ff425cc0e8418226f2ca1c47a772e8782d5 Mon Sep 17 00:00:00 2001 From: Nicholas Lee Date: Mon, 29 May 2023 16:59:03 -0400 Subject: [PATCH] 100 start information task sang et al (#101) * feat: added information task files * feat: updated information task * feat: completed information task --- src/app/models/ParticipantData.ts | 10 + .../information-task.component.html | 45 ++++ .../information-task.component.scss | 46 ++++ .../information-task.component.spec.ts | 23 ++ .../information-task.component.ts | 204 ++++++++++++++++++ src/app/pages/tasks/task.module.ts | 2 + src/app/services/component-factory.service.ts | 3 + .../data-generation/stimuli-models.ts | 10 + .../stimuli/informationtask/deckOfCards.png | Bin 0 -> 10233 bytes tsconfig.base.json | 3 +- 10 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 src/app/pages/tasks/task-playables/information-task/information-task.component.html create mode 100644 src/app/pages/tasks/task-playables/information-task/information-task.component.scss create mode 100644 src/app/pages/tasks/task-playables/information-task/information-task.component.spec.ts create mode 100644 src/app/pages/tasks/task-playables/information-task/information-task.component.ts create mode 100644 src/assets/images/stimuli/informationtask/deckOfCards.png diff --git a/src/app/models/ParticipantData.ts b/src/app/models/ParticipantData.ts index 77e5749..81e4a0b 100644 --- a/src/app/models/ParticipantData.ts +++ b/src/app/models/ParticipantData.ts @@ -204,6 +204,16 @@ export class IowaGamblingTaskData extends BaseParticipantData { feePaid: number; } +export class InformationTaskData extends BaseParticipantData { + roundNum: number; + trialScore: number; + cumulativeRoundScore: number; + cumulativeRoundLength: number; + trialResponseTime: number; + exploited: boolean; + expectedToExploit: boolean; +} + export class ParticipantData { userId: string; studyId: number; diff --git a/src/app/pages/tasks/task-playables/information-task/information-task.component.html b/src/app/pages/tasks/task-playables/information-task/information-task.component.html new file mode 100644 index 0000000..f3ceae5 --- /dev/null +++ b/src/app/pages/tasks/task-playables/information-task/information-task.component.html @@ -0,0 +1,45 @@ +
+
+
+
Click on the deck or an uncovered card
+
+
+
+
+ {{ card }} +
+
+
+
+
+
{{ stimuli.cardValues.length - cardsDrawn.length }} cards in the deck
+ Deck of cards image +
+
+
+ [ + + {{ value }}{{ i < valuesSelected.length - 1 ? ', ' : '' }} + + ] +
+
+
Turns Taken: {{ valuesSelected.length }}
+
+ Turns Left: {{ stimuli.cardValues.length - valuesSelected.length }} +
+
Total Points: {{ totalPoints }}
+
+
+
+
+
diff --git a/src/app/pages/tasks/task-playables/information-task/information-task.component.scss b/src/app/pages/tasks/task-playables/information-task/information-task.component.scss new file mode 100644 index 0000000..50e9113 --- /dev/null +++ b/src/app/pages/tasks/task-playables/information-task/information-task.component.scss @@ -0,0 +1,46 @@ +.card { + border-radius: 4px; + border: 4px solid black; + color: green; + padding: 1rem; + display: flex; + width: 100px; + height: 150px; + justify-content: center; + font-size: 3rem; + font-weight: bold; + cursor: pointer; + -webkit-user-select: none; /* Safari */ + -ms-user-select: none; /* IE 10 and IE 11 */ + user-select: none; /* Standard syntax */ + + &:hover { + box-shadow: 1px 1px 10px black; + } +} + +.card-container { + width: 10%; + height: 150px; + display: flex; + align-items: center; + justify-content: center; +} + +.cards-container { + width: 100%; + height: 400px; + display: flex; + flex-wrap: wrap; +} + +.deck { + &:hover { + opacity: 0.6; + cursor: pointer; + } +} + +.largest-card { + color: red !important; +} diff --git a/src/app/pages/tasks/task-playables/information-task/information-task.component.spec.ts b/src/app/pages/tasks/task-playables/information-task/information-task.component.spec.ts new file mode 100644 index 0000000..ca56fe1 --- /dev/null +++ b/src/app/pages/tasks/task-playables/information-task/information-task.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InformationTaskComponent } from './information-task.component'; + +describe('InformationTaskComponent', () => { + let component: InformationTaskComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ InformationTaskComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(InformationTaskComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/tasks/task-playables/information-task/information-task.component.ts b/src/app/pages/tasks/task-playables/information-task/information-task.component.ts new file mode 100644 index 0000000..d2f5cda --- /dev/null +++ b/src/app/pages/tasks/task-playables/information-task/information-task.component.ts @@ -0,0 +1,204 @@ +import { Component, HostListener, OnInit } from '@angular/core'; +import { AbstractBaseTaskComponent } from '../base-task'; +import { TimerService } from 'src/app/services/timer.service'; +import { LoaderService } from 'src/app/services/loader/loader.service'; +import { thisOrDefault, throwErrIfNotDefined } from 'src/app/common/commonMethods'; +import { TaskPlayerState } from '../task-player/task-player.component'; +import { StimuliProvidedType } from 'src/app/models/enums'; +import { ComponentName } from 'src/app/services/component-factory.service'; +import { DataGenerationService } from 'src/app/services/data-generation/data-generation.service'; +import { InformationTaskData } from 'src/app/models/ParticipantData'; +import { InformationTaskStimuliSet, InformationTaskStimulus } from 'src/app/services/data-generation/stimuli-models'; +import { TranslateService } from '@ngx-translate/core'; + +interface InformationTaskMetadata { + componentName: ComponentName; + componentConfig: { + numTrials: number; + roundNum: number; + isPractice: boolean; + stimuliConfig: { + type: StimuliProvidedType; + stimuli: InformationTaskStimuliSet; + }; + }; +} + +export enum InformationTaskCache { + TOTAL_SCORE = 'information-task-total-score', + OPTIMAL_SCORE = 'information-task-optimal-score', + STATUS_TEXT = 'information-task-status-text', +} + +@Component({ + selector: 'app-information-task', + templateUrl: './information-task.component.html', + styleUrls: ['./information-task.component.scss'], +}) +export class InformationTaskComponent extends AbstractBaseTaskComponent { + // config variables variables + private numTrials: number; + private roundNum: number; // determines which deck to use (1-6), translates into blockNum + private isPractice: boolean; + + // high level variables + taskData: InformationTaskData[]; + stimuli: InformationTaskStimuliSet; + currentStimuliIndex: number = 0; + cardsDrawn: number[]; + valuesSelected: number[]; + taskStarted: boolean = false; + roundStartTime: number; + trialNum: number = 0; + + // local state variables + + get currentStimulus(): InformationTaskStimulus { + return this.stimuli.cardValues[this.currentStimuliIndex]; + } + + get currentTrial(): InformationTaskData { + // will return null if taskData is not defined or if it has length of 0 + return this.taskData?.length > 0 ? this.taskData[this.taskData.length - 1] : null; + } + + get largestDrawnCardValue(): number { + return this.cardsDrawn.reduce((acc, curr) => (curr > acc ? curr : acc), 0); + } + + get totalPoints(): number { + return this.valuesSelected.reduce((acc, curr) => acc + curr, 0); + } + + // translation mapping + translationMapping = { + scoreStatusTextLower: { + en: 'You scored lower', + fr: '', + }, + scoreStatusTextEqual: { + en: 'You were equal!', + fr: '', + }, + scoreStatusTextHigher: { + en: 'You scored higher!', + fr: '', + }, + }; + + constructor( + protected timerService: TimerService, + protected dataGenService: DataGenerationService, + protected loaderService: LoaderService, + private translateService: TranslateService + ) { + super(loaderService); + } + + configure(metadata: InformationTaskMetadata, config?: TaskPlayerState) { + try { + this.userID = throwErrIfNotDefined(config.userID, 'no user ID defined'); + this.studyId = throwErrIfNotDefined(config.studyID, 'no study code defined'); + + this.numTrials = throwErrIfNotDefined(metadata.componentConfig.numTrials, 'num trials not defined'); + this.roundNum = throwErrIfNotDefined(metadata.componentConfig.roundNum, 'roundNum is not defined'); + this.isPractice = thisOrDefault(metadata.componentConfig.isPractice, false); + } catch (error) { + throw new Error('values not defined, cannot start study'); + } + + this.config = config; + if (metadata.componentConfig.stimuliConfig.type === StimuliProvidedType.HARDCODED) + this.stimuli = metadata.componentConfig.stimuliConfig.stimuli; + } + + start(): void { + console.log(this.stimuli); + // configure game + this.taskStarted = true; + + this.taskData = []; + this.cardsDrawn = []; + this.valuesSelected = []; + this.currentStimuliIndex = 0; + this.trialNum = 0; + + this.roundStartTime = Date.now(); + super.start(); + } + + beginRound() { + this.timerService.clearTimer(); + this.timerService.startTimer(); + } + + handleRoundInteraction(cardType: 'newCard' | 'existingCard', existingCardVal?: number) { + if (!this.taskStarted) return; + + const newCardVal = this.currentStimulus; + + let cardValue: number; + if (cardType === 'newCard') { + this.cardsDrawn.push(newCardVal.cardValue); + cardValue = newCardVal.cardValue; + } else { + cardValue = existingCardVal; + } + + this.valuesSelected.push(cardValue); + + this.taskData.push({ + userID: this.userID, + studyId: this.studyId, + submitted: this.timerService.getCurrentTimestamp(), + isPractice: this.isPractice, + trial: ++this.trialNum, + roundNum: this.roundNum, + trialScore: cardValue, + cumulativeRoundLength: Date.now() - this.roundStartTime, + cumulativeRoundScore: + this.taskData.length <= 0 + ? cardValue + : this.taskData[this.taskData.length - 1].cumulativeRoundScore + cardValue, + exploited: cardType === 'existingCard', + expectedToExploit: newCardVal.expectedToExploit, + trialResponseTime: this.timerService.stopTimerAndGetTime(), + }); + super.handleRoundInteraction(null); + } + + async completeRound() { + super.completeRound(); + } + + async decideToRepeat(): Promise { + if (this.trialNum >= this.numTrials) { + this.taskStarted = false; + const totalScore = this.taskData.reduce((acc, currVal) => { + return acc + currVal.trialScore; + }, 0); + + const optimalScore = this.stimuli.optimalScore; + + console.log({ totalScore, optimalScore }); + + const statusText = + totalScore < optimalScore + ? this.translationMapping.scoreStatusTextLower[this.translateService.currentLang] + : totalScore === optimalScore + ? this.translationMapping.scoreStatusTextEqual[this.translateService.currentLang] + : this.translationMapping.scoreStatusTextHigher[this.translateService.currentLang]; + + // this will replace the previous round + this.config.setCacheValue(InformationTaskCache.TOTAL_SCORE, totalScore); + this.config.setCacheValue(InformationTaskCache.OPTIMAL_SCORE, optimalScore); + this.config.setCacheValue(InformationTaskCache.STATUS_TEXT, statusText); + + super.decideToRepeat(); + } else { + this.currentStimuliIndex++; + this.beginRound(); + return; + } + } +} diff --git a/src/app/pages/tasks/task.module.ts b/src/app/pages/tasks/task.module.ts index b228eff..f4e4c5a 100644 --- a/src/app/pages/tasks/task.module.ts +++ b/src/app/pages/tasks/task.module.ts @@ -41,6 +41,7 @@ import { BlankComponent } from './blank/blank.component'; import { ProbabilisticLearningTaskComponent } from './task-playables/probabilistic-learning-task/probabilistic-learning-task.component'; import { OptionDisplayComponent } from './shared/option-display/option-display.component'; import { IowaGamblingTaskComponent } from './task-playables/iowa-gambling-task/iowa-gambling-task.component'; +import { InformationTaskComponent } from './task-playables/information-task/information-task.component'; @NgModule({ declarations: [ @@ -64,6 +65,7 @@ import { IowaGamblingTaskComponent } from './task-playables/iowa-gambling-task/i TaskPlayerComponent, TaskSwitchingComponent, TrailMakingComponent, + InformationTaskComponent, EmbeddedPageComponent, diff --git a/src/app/services/component-factory.service.ts b/src/app/services/component-factory.service.ts index 1b832d2..35411d1 100644 --- a/src/app/services/component-factory.service.ts +++ b/src/app/services/component-factory.service.ts @@ -20,6 +20,7 @@ import { EmbeddedPageComponent } from '../pages/tasks/task-playables/embedded-pa import { InfoDisplayComponent } from '../pages/tasks/task-playables/info-display/info-display.component'; import { ProbabilisticLearningTaskComponent } from '../pages/tasks/task-playables/probabilistic-learning-task/probabilistic-learning-task.component'; import { IowaGamblingTaskComponent } from '../pages/tasks/task-playables/iowa-gambling-task/iowa-gambling-task.component'; +import { InformationTaskComponent } from '../pages/tasks/task-playables/information-task/information-task.component'; export enum ComponentName { // Generic components @@ -42,6 +43,7 @@ export enum ComponentName { FACE_NAME_ASSOCIATION_COMPONENT = 'FACENAMEASSOCIATIONCOMPONENT', PLT_COMPONENT = 'PLTCOMPONENT', IOWA_GAMBLING_COMPONENT = 'IOWAGAMBLINGCOMPONENT', + INFORMATION_TASK_COMPONENT = 'INFORMATIONTASKCOMPONENT', // Special Components EMBEDDED_PAGE_COMPONENT = 'EMBEDDEDPAGECOMPONENT', @@ -72,6 +74,7 @@ const ComponentMap = { [ComponentName.INFO_DISPLAY_COMPONENT]: InfoDisplayComponent, [ComponentName.PLT_COMPONENT]: ProbabilisticLearningTaskComponent, [ComponentName.IOWA_GAMBLING_COMPONENT]: IowaGamblingTaskComponent, + [ComponentName.INFORMATION_TASK_COMPONENT]: InformationTaskComponent, }; @Injectable({ diff --git a/src/app/services/data-generation/stimuli-models.ts b/src/app/services/data-generation/stimuli-models.ts index 484b42d..761a9c8 100644 --- a/src/app/services/data-generation/stimuli-models.ts +++ b/src/app/services/data-generation/stimuli-models.ts @@ -164,3 +164,13 @@ export class IowaGamblingTaskStimulus { moneyWon: number; feePaid: number; } + +export class InformationTaskStimuliSet { + optimalScore: number; + cardValues: InformationTaskStimulus[]; +} + +export class InformationTaskStimulus { + cardValue: number; + expectedToExploit: boolean; +} diff --git a/src/assets/images/stimuli/informationtask/deckOfCards.png b/src/assets/images/stimuli/informationtask/deckOfCards.png new file mode 100644 index 0000000000000000000000000000000000000000..6206013ee03e42af04f8ee4989c1de5172b65159 GIT binary patch literal 10233 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 literal 0 HcmV?d00001 diff --git a/tsconfig.base.json b/tsconfig.base.json index 63e8b74..9fff3ad 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -16,6 +16,7 @@ }, "angularCompilerOptions": { "fullTemplateTypeCheck": true, - "strictInjectionParameters": true + "strictInjectionParameters": true, + "strictTempaltes": true } }